home *** CD-ROM | disk | FTP | other *** search
- // COPYRIGHT 1997 - by James McCue
-
- // This is SOME of the main module to the source code of
- // the game "Slow Runnings 1.11".
-
- // It's stupid to dump all the code into one source module...
-
- // I just ripped most of it out!
-
- // This code was such a pigsty - it was embarrassing!
-
-
- // ...it still is!
-
- // I'M REFINING THE CODE - AND BEGINNING WORK ON SOMETHING ELSE
- // 3D!!!
-
- // THIS SOURCE CODE AND IT'S ASSOCIATED FILES ARE DISTRIBUTED AS IS,
- // AND WITHOUT WARRANTY OF ANY KIND!
-
- // JAMES MCCUE MAKES NO CLAIMS AS TO THE MARKETABLITY OF THIS
- // SOURCE CODE, OR ANYTHING MADE WITH IT.
-
- // NOR DOES JAMES MCCUE MAKE ANY CLAIMS ABOUT THIS SOFTWARE'S
- // USEFULNESS FOR ANY PURPOSE.
-
- // JAMES MCCUE IS NOT RESPONSIBLE FOR ANY DAMAGE (SOFTWARE OR
- // HARDWARE) THAT ARISES FROM THE USE OF THIS CODE - NOR ANY
- // EXECUTABLES MADE WITH/FROM IT...
-
- // I hope you can learn something from this...
-
- #include <io.h>
- #include <conio.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <dos.h>
- #include <bios.h>
- #include <fcntl.h>
- #include <memory.h>
- #include <malloc.h>
- #include <math.h>
- #include <errno.h>
- #include <string.h>
- #include <search.h> // this one is needed for qsort()
-
- #include "magic3.h"
- #include "magic4.h"
- #include "magic5.h"
- #include "magic6.h"
- #include "magic8.h"
- //#include <time.h>
-
-
- // D E F I N E S /////////////////////////////////////////////////////////////
-
- // #define DEBUG 1
-
- #define OVERBOARD 44 // the absolute closest a player can get to a wall
-
- #define INTERSECTION_FOUND 1
-
- // enemy states...
-
- #define PURSUING 0
- #define WAITING 1
- #define FIRING 2
- #define DEAD 3
- #define EVADING 4
- #define DYING 5
- #define STANDING_AND_FIRING 6
- #define HIT 7
-
- // PLAYER STATES..... //////////////////////////////////////////////
-
- #define PLAYER_NOT_FIRING 0
- #define PLAYER_FIRING 1
-
- // SOUNDS //////////////////////////////////////////////
-
- #define door_sound 0
- #define firing_sound 1
- #define enemy_death_sound 2
- #define enemy_shoot_sound 3
- #define map_warp_sound 4
-
- // for Math stuff..../////////////////////////////
-
- #define Pi (float)3.1415926
- #define DEG_TO_RAD ((float)3.1415926/(float)180)
-
- #define WORLD_ROWS 32
- #define WORLD_COLUMNS 32
- #define CELL_X_SIZE 64
- #define CELL_Y_SIZE 64
-
- #define SWATCH_WIDTH 64
-
- #define CELL_X_SIZE_FP 6 // <- used for bit-wize shifting
- #define CELL_Y_SIZE_FP 6 // because it is faster than
- // multiplication and division
-
- // size of overall game world
-
- #define WORLD_X_SIZE (WORLD_COLUMNS * CELL_X_SIZE)
- #define WORLD_Y_SIZE (WORLD_ROWS * CELL_Y_SIZE)
-
- #define MAX_SCALE 235 // maximum size and wall "sliver" can be
-
-
- #define WALL_MIDDLE_OFFSET (32<<6)
- #define WALL_MIDDLE_MINUS_OFFSET (31<<6)
-
- #define WOIK_OFFSET_1(y_off) (WALL_MIDDLE_OFFSET - scale_row[y_off])
- #define WOIK_OFFSET_2(y_off) (WALL_MIDDLE_OFFSET + scale_row[y_off])
-
- #define BORDER_COLOR_1 42
- #define BORDER_COLOR_2 48
- #define BORDER_COLOR_3 54
- #define BORDER_COLOR_4 48
-
- #define OPENING 1
- #define CLOSING 2
- #define OPEN 3
- #define CLOSED 4
-
- #define DOSALLOC 0
-
- #define MAX_OBJECTS 55
-
- #define MAX_ENEMIES 20
-
- // GLOBALS /////////////////////////////////////////////
-
- // constants used to represent angles
-
- int my_size = 1216; // for a 90 degree view cone
-
- int my_v_scale = 9500; // for 90 big-ass degrees of view coneage carnage!
-
- int my_height = 148;
- int my_right = 312;
- int my_left = 8;
-
- int COLUMN_OFFSET= 311;
-
- int ANGLE_360;
-
- int ANGLE_180;
- int ANGLE_90;
- int ANGLE_75;
- int ANGLE_60;
- int ANGLE_45;
- int ANGLE_30;
- int ANGLE_15;
- int ANGLE_6;
- int ANGLE_5;
- int ANGLE_4;
- int ANGLE_2;
- int ANGLE_1;
- int ANGLE_0;
-
- // some ODDBALL angles
-
- int ANGLE_315;
- int ANGLE_270;
- int ANGLE_225;
- int ANGLE_135;
- int ANGLE_10;
- int ANGLE_9;
- int ANGLE_8;
- int ANGLE_7;
- // ... and some possible view cone values
- int ANGLE_80;
- int ANGLE_70;
- // for 'shifting the parachute' (?!)
-
- int ANGLE_23;
-
- int VIEW_CONE;
-
- int HALF_VIEW_CONE;
-
- // conversion constants from radians to degrees and vice-versa
-
- float ANGULAR_INCREMENT;
-
-
- float RAD_TO_DEG;
-
- // conversion constants from radians to degrees and vicversa
-
- // MORE GLOBALS //////////////////////////////
-
- int WINDOW_HEIGHT;
-
- int WINDOW_HALF_HEIGHT;
-
- int WINDOW_MIDDLE;
-
- int WINDOW_MIDDLE_MINUS;
-
- int WINDOW_TOP;
- int WINDOW_BOTTOM;
- int WINDOW_LEFT;
- int WINDOW_RIGHT;
-
- int VERTICAL_SCALE; // used to scale the "slivers" to get proper
-
- int total_world_doors = 0;
-
- typedef long fixed;
-
- int toggle = 0;
-
- // SOUND ////////////////
-
- sound global_sounds[7];
-
- // MUSIC //////////////////////////////////////////////
-
- music song;
-
-
- typedef struct object_type
- {
- int kind_of_object;
- long x;
- long y;
- long dist;
- long angle;
- int id_number;
- } objects, objects_ptr;
-
- typedef struct statist_typ
- {
- float width_factor;
- long Scale_Factor;
- int Is_Multi_View;
- int Is_Half_Height;
- } stats, stats_ptr;
-
- typedef struct Enemy_type
- {
- objects vitals;
- int enem_num;
- int state;
- int threshold;
- int hit_points;
- int pat_num;
- } enemy_objects, enemy_objects_ptr;
-
-
- typedef struct door_type
- {
- int door_y;
- int door_x;
- int door_state;
- int door_block_type;
- int locked;
- int door_speed;
- int door_increment;
- int door_wait_to_close;
- } door, door_ptr;
-
- typedef struct wall_type
- {
- char block_type;
- short door_id;
- } wall, wall_ptr;
-
- typedef struct save_game
- {
- int cur_strength;
- int cur_ammo;
- int cur_map;
- int cur_level;
- } savestr, savestr_ptr;
-
- typedef struct name_typ
- {
- unsigned char name[13];
- } name_obj, name_obj_ptr;
-
- name_obj names[5];
-
- door doors[20];
-
- int objects_found = 0;
-
- int OVERBOARD_FOR_ENEMIES = 52; // absolute closest enemies can get to a wall
-
- int got_key = 0;
-
-
- // look up tables! ////////////////////////////////////////////////////////
-
- wall world[WORLD_ROWS][WORLD_COLUMNS]; // pointer to matrix of cells that make up
- // world
- char far *Block_Map[WORLD_ROWS]; // pointer to block map...
-
- float far *tan_table; // tangent tables used to compute initial
- float far *inv_tan_table; // intersections with rays
-
-
- float far *y_step; // x and y steps, used to find intersections
- float far *x_step; // after initial one is found
-
-
- float far *cos_table; // used to cancel out fishbowl effect
-
- float far *inv_cos_table; // used to compute distances by calculating
- float far *inv_sin_table; // the hypontenuse
-
- int *scale_table[MAX_SCALE+1]; // table with pre-computed scale indices
-
- // parmeter block used by assembly language sliver engine
-
- char far *sliver_texture; // pointer to texture being rendered
- int sliver_column; // index into texture i.e. which column of texture
- int sliver_top; // starting Y position to render at
- int sliver_bottom;
- int sliver_scale; // overall height of sliver
- int sliver_ray; // current ray being cast
- int sliver_clip; // index into texture after clipping
- int *scale_row; // row of scale value look up table to use
-
- // OBJECT LISTS
-
- objects *object_list;
-
- stats obj_statistic_list[7];
-
-
- objects *initial_object_list;
-
- enemy_objects *enemies;
-
-
- // G L O B A L S ////////////////////////////////////////////////////////////
-
- pcx_picture back_pcx,
- image_pcx;
-
- sprite wall_frames;
-
- sprite duck_frames;
- sprite duck_death;
- sprite ob_frames;
- sprite the_gun;
-
- int is_multi = 0; // for multiview sprites!
- int Player_Strength = 63;
- int just_grabbed_something = 0;
-
- long x, y,view_angle;
-
- int index1,
- counter,
- counter2;
-
- int duck_pattern[24] = {0,0,0,0,0,0,1,1,1,1,1,1,2,2,2,2,2,2,1,1,1,1,1,1};
-
- int PAT_LIMIT = 24;
-
- int increment=0; // used to determine how far a door is open
- int color;
- int what_obj = 0;
-
- int gun_top = 108;
-
- int Got_Rapid_Fire = 0;
-
- long vz_buffer[320+1]; // vertical scanline Zbuffer for determining
- // sprite_visibility
-
- int Ammo_Color = 14;
- int Vitality_Color = 119;
-
- int Player_Ammo = 28;
-
- int beat_it = 0;
-
- // structure for slivers, used in order to interleave the ray casting
- // with the time spent waiting for the PAGE FLIP to take hold!
- // The elements of this structure are set in the function RAY_CASTER
- // and used by DRAW_WALLS in it's subsequent calls to RENDER_SLIVER!
-
- typedef struct buffer_typ
- {
- char far *sliv_texture; // pointer to texture being rendered
- char sliv_hit_type;
- unsigned short sliv_column; // index into texture i.e. which column of texture
- unsigned short sliv_top; // starting Y position to render at
- unsigned short sliv_bottom;
- int sliv_scale; // overall height of sliver
- int sliv_ray; // current ray being cast
- int sliv_clip; // index into texture after clipping
- int scale_r; // row of scale value look up table to use
- } sliv_buff, sliv_ptr;
-
- sliv_buff sliver_buffer[320+1]; // one structure for all columns drawn
-
-
- int v_320[200]; // lookups to speed up the math for drawing pixels
- int v_80[200];
- int h_320[320];
-
- int Number_Of_Fixed_Objects = 0;
- int Number_Of_Enemies = 0;
-
- int player_state = PLAYER_NOT_FIRING;
-
- int AIMED = 0;
-
- int digital_enabled = 0;
-
- int music_enabled = 0;
-
- long color_1, color_ceil, color_floor;
-
- unsigned char far *back_up = (unsigned char far *)0xA000C000L;
-
- RGB_color global_color;
-
- RGB_color color_all;
- RGB_color old_all[256];
-
- int which_map = 0;
- int Red_Factor = 16;
- int at_end = 0, really_at_end = 0;
- int aimed_sort_of = 0;
-
- int in_view = 0;
- int New_Lease_On_Life = 0;
-
- int pal_reg, id_number;
- int Restore_Black = 0;
-
- int Damage = 0;
-
- int pat_start = 0;
- int rotate_em = 1;
- char where_am_i[80];
- // F U N C T I O N P R O T O T Y P E S /////////////////////////////
-
- void (*rend_func_ptr) ();
-
-
- int Object_Sort_Function(objects *arg1, objects *arg2);
-
- // creates the scale table
-
- void Create_Scale_Data(int scale, int *row);
- void Create_Scale_Data2(int scale, int *row);
-
-
- // Blits...
-
- int Parse_Commands(int argc, char **argv);
-
- void Draw_Walls(void);
-
- // allocates/initializes tables
-
- void Build_Tables(void);
-
- void Load_64x64_Sprites(sprite_ptr sprite_set, char *filename, int num_cells);
-
- // World Initialization functions...
-
- void Allocate_World(void);
-
- int Load_World(int lev_numb);
-
- // the RAY CASTER!
-
- void Ray_Caster(void);
-
- void Draw_ReDraw_Frame(void);
-
- // self explanatory...
-
- // again, self explanatory...
-
- void Translate_Player(long dx, long dy);
-
- void Process_Doors(void);
-
-
- void Render_Sliver(void);
-
- void Render_Sliver_Mask(void);
-
- void Render_Sliver_Mask_Special(void);
-
- void Render_Sliver_Mask_Just_Bottom(void);
-
- void Render_UpsideDwn_Mask_Bottom(void);
-
- void Level_Select(int well);
-
- int Slot_Selection(void);
-
- void Refresh_Name_List(int what_shade);
-
- int Load_Game(void);
-
- void New_Game(void);
-
- void Save_Game(void);
-
- void Make_Light_Metallic_Blue_Palette(void);
-
- void Make_Gold_Palette(void);
-
- void Make_Gray_Palette(void);
-
- void Make_Blue_Palette(void);
-
- void Make_Blue_Palette_OAAT(int delta, int erase_trail);
-
- void Make_Cyan_Palette_OAAT(int delta, int erase_trail);
-
- void Make_Gold_Palette_OAAT(int delta, int erase_trail);
-
- void Make_Gray_Palette_OAAT(int delta, int erase_trail);
-
- void Rotate_Em(int well);
-
- // BEGINNING OF CODE //////////////////////////////////////////////////////
-
-
- void Render_Sliver(void)
- {
- // this is yet another version of the sliver scaler, however it uses look up
- // tables with pre-computed scale indices.
-
- // this draws vertical slivers from the middle of the strip to the top,
- // and from the middle of the strip to the bottom.
-
- register char far *work_sprite;
- int far *row;
-
- register int work_offset=0,offset,temp_offset,y_off,scale_off;
-
- // alias a pointer to sprite for ease of access
-
- work_sprite = sliver_texture;
-
- // compute offset of sprite in video buffer
-
- temp_offset = v_80[WINDOW_MIDDLE_MINUS] + h_320[sliver_ray];
-
- // render top half of wall sliver
-
- offset = temp_offset;
-
- work_offset = WALL_MIDDLE_OFFSET - scale_row[0];
-
- video_buffer[offset] = work_sprite[work_offset+sliver_column];
-
- for (y_off=1; y_off<sliver_scale; y_off++)
- {
-
- offset -= 80;
- work_offset = WALL_MIDDLE_OFFSET - scale_row[y_off];
-
- video_buffer[offset] = work_sprite[work_offset+sliver_column];
-
- } // end for y
-
- // render bottom half of wall sliver
-
- offset = temp_offset + 80;
-
- work_offset = WALL_MIDDLE_OFFSET;
-
- video_buffer[offset] = work_sprite[work_offset+sliver_column];
-
- for (y_off=0; y_off<(sliver_scale-1); y_off++)
- {
-
-
- offset += 80;
- work_offset = WALL_MIDDLE_OFFSET + scale_row[y_off];
-
- video_buffer[offset] = work_sprite[work_offset+sliver_column];
- } // end for y
-
- } // end Render_Sliver
-
- void Render_Sliver_Mask(void)
- {
- // this is yet another version of the sliver scaler, however it uses look up
- // tables with pre-computed scale indices. in the end I converted this to
- // assembly for speed
-
- register char far *work_sprite;
- int far *row;
-
- register int work_offset=0,offset,y_off,scale_off;
-
- // alias proper data row
-
- scale_off = sliver_clip;
-
- // alias a pointer to sprite for ease of access
-
- work_sprite = sliver_texture;
-
- // compute offset of sprite in video buffer
-
- offset = v_80[WINDOW_MIDDLE_MINUS] + h_320[sliver_ray];
-
- work_offset = WALL_MIDDLE_OFFSET - scale_row[0];
-
- if (work_sprite[work_offset+sliver_column]!=0)
- video_buffer[offset] = work_sprite[work_offset+sliver_column];
-
- for (y_off=1; y_off<sliver_scale; y_off++)
- {
-
- offset -= 80;
- work_offset = WALL_MIDDLE_OFFSET - scale_row[y_off];
-
- if (work_sprite[work_offset+sliver_column]!=0)
- video_buffer[offset] = work_sprite[work_offset+sliver_column];
-
- } // end for y
-
- offset = v_80[WINDOW_MIDDLE] + h_320[sliver_ray];
-
- work_offset = WALL_MIDDLE_OFFSET;
-
- if (work_sprite[work_offset+sliver_column]!=0)
- video_buffer[offset] = work_sprite[work_offset+sliver_column];
-
- for (y_off=0; y_off<(sliver_scale-1); y_off++)
- {
-
-
- offset += 80;
- work_offset = WALL_MIDDLE_OFFSET + scale_row[y_off];
-
- if (work_sprite[work_offset+sliver_column]!=0)
- video_buffer[offset] = work_sprite[work_offset+sliver_column];
- } // end for y
-
- } // end Render_Sliver_Mask
-
- void Render_Sliver_Mask_Special(void)
- {
- // this is yet another version of the sliver scaler, however it uses look up
- // tables with pre-computed scale indices. in the end I converted this to
- // assembly for speed
-
- register char far *work_sprite;
- int far *row;
-
- register int work_offset=0,offset,y_off,scale_off;
- register int Special_Offset;
-
- // alias proper data row
-
- scale_off = sliver_clip;
-
- // alias a pointer to sprite for ease of access
-
- work_sprite = sliver_texture;
-
- // compute offset of sprite in video buffer
-
- Special_Offset = sliver_scale-(sliver_scale/3);
-
- offset = v_80[WINDOW_MIDDLE_MINUS-(Special_Offset-1)] + h_320[sliver_ray];
-
- work_offset = WALL_MIDDLE_OFFSET - scale_row[0];
-
- if (work_sprite[work_offset+sliver_column]!=0)
- video_buffer[offset] = work_sprite[work_offset+sliver_column];
-
- for (y_off=Special_Offset; y_off<sliver_scale; y_off++)
- {
-
- offset -= 80;
- work_offset = WALL_MIDDLE_OFFSET - scale_row[y_off];
-
- if (work_sprite[work_offset+sliver_column]!=0)
- video_buffer[offset] = work_sprite[work_offset+sliver_column];
-
- } // end for y
-
- offset = v_80[WINDOW_MIDDLE+(Special_Offset)] + h_320[sliver_ray];
-
- work_offset = WALL_MIDDLE_OFFSET;
-
- if (work_sprite[work_offset+sliver_column]!=0)
- video_buffer[offset] = work_sprite[work_offset+sliver_column];
-
- for (y_off=Special_Offset; y_off<(sliver_scale-1); y_off++)
- {
-
-
- offset += 80;
- work_offset = WALL_MIDDLE_OFFSET + scale_row[y_off];
-
- if (work_sprite[work_offset+sliver_column]!=0)
- video_buffer[offset] = work_sprite[work_offset+sliver_column];
- } // end for y
-
- } // end Render_Sliver_Mask_Special
-
- void Render_Sliver_Mask_Just_Bottom(void)
- {
- // this is yet another version of the sliver scaler, however it uses look up
- // tables with pre-computed scale indices. in the end I converted this to
- // assembly for speed
-
- register char far *work_sprite;
- int far *row;
-
- register int work_offset=0,offset,y_off,scale_off;
-
- // alias proper data row
-
-
- // alias a pointer to sprite for ease of access
-
- work_sprite = sliver_texture;
-
- // compute offset of sprite in video buffer
-
-
- offset = v_80[WINDOW_MIDDLE] + h_320[sliver_ray];
-
- work_offset = WALL_MIDDLE_OFFSET;
-
- if (work_sprite[work_offset+sliver_column]!=0)
- video_buffer[offset] = work_sprite[work_offset+sliver_column];
-
- for (y_off=0; y_off<(sliver_scale-1); y_off++)
- {
-
-
- offset += 80;
- work_offset = WALL_MIDDLE_OFFSET + scale_row[y_off];
-
- if (work_sprite[work_offset+sliver_column]!=0)
- video_buffer[offset] = work_sprite[work_offset+sliver_column];
- } // end for y
-
- } // end Render_Sliver_Mask_Just_Bottom
-
- void Render_UpsideDwn_Mask_Bottom(void)
- {
- // this is yet another version of the sliver scaler, however it uses look up
- // tables with pre-computed scale indices. in the end I converted this to
- // assembly for speed
-
- register char far *work_sprite;
- int far *row;
-
- register int work_offset=0,offset,y_off,scale_off;
-
- // alias proper data row
-
-
- // alias a pointer to sprite for ease of access
-
- work_sprite = sliver_texture;
-
- // compute offset of sprite in video buffer
-
-
- offset = v_80[WINDOW_MIDDLE] + h_320[sliver_ray];
-
- work_offset = WALL_MIDDLE_OFFSET;
-
- if (work_sprite[work_offset+sliver_column]!=0)
- video_buffer[offset] = work_sprite[work_offset+sliver_column];
-
- for (y_off=0; y_off<(sliver_scale-1); y_off++)
- {
-
-
- offset -= 80;
- work_offset = WALL_MIDDLE_OFFSET + scale_row[y_off];
-
- if (work_sprite[work_offset+sliver_column]!=0)
- video_buffer[offset] = work_sprite[work_offset+sliver_column];
- } // end for y
-
- } // end Render_UpsideDwn_Mask_Bottom
-
-
- int Build_Object_Tables(char *file)
- {
- // this function opens the input file and loads the OBJECT data from it
-
- FILE *fp, *fopen();
- int index,row,column,ob_num,gunner_num;
- char buffer[WORLD_COLUMNS+2],ch;
-
- // allocate space for object lists...
-
- // init ob counter
-
- ob_num = 0;
- gunner_num = 0;
- // open the file
-
- if (!(fp = fopen(file,"r")))
- return(0);
-
- // load in the data
-
- for (row=0; row<WORLD_ROWS; row++)
- {
- // load in the next row
-
- for (column=0; column<WORLD_COLUMNS; column++)
- {
-
- while((ch = getc(fp))==10){} // filter out CR
-
- // translate character to integer
-
- if ((ch == '0') || (ch == '1') || (ch == '6'))
- {
- ch = ch - '0';
-
- initial_object_list[ob_num].x = (column<<CELL_X_SIZE_FP)+32;
- initial_object_list[ob_num].y = (((WORLD_ROWS-1) - row)<<CELL_Y_SIZE_FP)+32;
- initial_object_list[ob_num].angle = ANGLE_0;
- initial_object_list[ob_num].kind_of_object = ch;
- initial_object_list[ob_num].dist = 0;
-
- ob_num++;
- }
-
-
- } // end for column
-
- // process the row
-
- } // end for row
-
- // close the file
-
- fclose(fp);
-
- if (!(fp = fopen(file,"r")))
- return(0);
-
- // load in the data
-
- for (row=0; row<WORLD_ROWS; row++)
- {
- // load in the next row
-
- for (column=0; column<WORLD_COLUMNS; column++)
- {
-
- while((ch = getc(fp))==10){} // filter out CR
-
- // translate character to integer
-
- if ((ch == '4') || (ch == '5'))
- {
- ch = ch - '0';
-
- initial_object_list[ob_num].x = (column<<CELL_X_SIZE_FP)+32;
- initial_object_list[ob_num].y = (((WORLD_ROWS-1) - row)<<CELL_Y_SIZE_FP)+32;
- initial_object_list[ob_num].angle = ANGLE_0;
- initial_object_list[ob_num].kind_of_object = ch;
- initial_object_list[ob_num].dist = 0;
-
- ob_num++;
- }
-
-
- } // end for column
-
- // process the row
-
- } // end for row
-
- // close the file
-
- fclose(fp);
-
- Number_Of_Fixed_Objects = ob_num;
-
- ob_num = 0;
-
- if (!(fp = fopen(file,"r")))
- return(0);
-
- // load in the data
-
- for (row=0; row<WORLD_ROWS; row++)
- {
- // load in the next row
-
- for (column=0; column<WORLD_COLUMNS; column++)
- {
-
- while((ch = getc(fp))==10){} // filter out CR
-
- // translate character to integer
-
- if ((ch == '2') || (ch == '3'))
- {
- ch = ch - '0';
-
- enemies[ob_num].vitals.x = (column<<CELL_X_SIZE_FP)+32;
- enemies[ob_num].vitals.y = (((WORLD_ROWS-1) - row)<<CELL_Y_SIZE_FP)+32;
- enemies[ob_num].vitals.angle = ANGLE_0;
- enemies[ob_num].vitals.kind_of_object = ch;
- enemies[ob_num].vitals.dist = 0;
- enemies[ob_num].enem_num = ob_num;
-
- enemies[ob_num].state = WAITING;
- enemies[ob_num].threshold = 0;
- enemies[ob_num].hit_points = 5;
- enemies[ob_num].pat_num = 0;
-
- ob_num++;
- }
-
-
- } // end for column
-
- // process the row
-
- } // end for row
-
- // close the file
-
- fclose(fp);
-
- Number_Of_Enemies = ob_num;
-
- //return(1);
-
- } // end Build_Object_Tables
-
-
- void Find_and_Maybe_Plot_Objects(objects any_object, int ID_Number, int threshold)
- {
- long sub_view_left,sub_view_right;
- long sub2_view_right;
-
- long relative_angle;
- float diff_x,diff_y;
- long temp_buffer_check;
-
- long buffer_check;
-
- int *scale_column;
-
- int i;
- int indice;
- int scale;
-
- long object_x, object_y, object_dist, object_angle;
-
- fixed scale_factor;
- fixed planar_scale_factor;
- fixed sprite_dist;
- fixed adjusted_index;
- int sprite_width,sprite_index,left,x_location;
- int sprite_left,sprite_right;
- int which_object;
-
- int sides_per_object = 8;
- int angles_per_side = ANGLE_45;
- static int temp_what_half = 0;
-
- int what_half;
-
- int pquad;
- int oquad;
- int j;
-
- // beginning of function code
-
- object_x = any_object.x;
- object_y = any_object.y;
- object_dist = any_object.dist;
- object_angle = any_object.angle;
- which_object = any_object.kind_of_object;
-
- what_half = 0;
-
- diff_x = (x - object_x);
- diff_y = (y - object_y);
-
- if ((diff_x>1000) || (diff_x < -1000)) return;
-
- if ((diff_y>1000) || (diff_y < -1000)) return;
-
- sprite_dist = object_dist;
-
- if ((sprite_dist<(30)) || (sprite_dist>(1000))) return;
-
-
- if (diff_y == 0)
- {
- if (diff_x < 0)
- relative_angle = ANGLE_0;
- else
- relative_angle = ANGLE_180;
- }
- else
- if (diff_x == 0)
- {
- if (diff_y < 0)
- relative_angle = ANGLE_90;
- else
- relative_angle = ANGLE_270;
- }
- else
- {
- if (diff_x < 0) diff_x = diff_x *-1;
- if (diff_y < 0) diff_y = diff_y *-1;
-
- relative_angle = (long)((atan((double)diff_y/(double)diff_x))*(RAD_TO_DEG));
-
- diff_x = (x - object_x);
- diff_y = (y - object_y);
-
- if (diff_x > 0)
- {
- if(diff_y > 0)
- relative_angle = ANGLE_180 + relative_angle;
- else
- if(diff_y < 0)
- relative_angle = ANGLE_180 - relative_angle;
- }
- else
- if (diff_x < 0)
- {
- if(diff_y > 0)
- relative_angle = ANGLE_360 - relative_angle;
-
- }
- }
-
- sub_view_left = view_angle + HALF_VIEW_CONE + ANGLE_5;
- sub_view_right = view_angle - HALF_VIEW_CONE - ANGLE_5;
- sub2_view_right = view_angle - HALF_VIEW_CONE;
-
- // Adjust angles, because around view_angle 0 things
- // get tricky...
-
- if (sub2_view_right<ANGLE_5)
- {
- sub2_view_right += ANGLE_360;
- }
-
- if (sub_view_left>ANGLE_360) sub_view_left -= ANGLE_360;
-
- if (sub_view_right<ANGLE_0)
- {
- sub_view_right += ANGLE_360;
- }
- if (sub_view_left>ANGLE_360) sub_view_left -= ANGLE_360;
-
- if (sub_view_right<ANGLE_0)
- {
- sub_view_right += ANGLE_360;
- }
- if (sub_view_right > sub_view_left) // If looking towards the right
- {
- if (relative_angle >= sub_view_right) // Cal. view column of object
- buffer_check = relative_angle - sub2_view_right;
- else
- buffer_check = (relative_angle+ANGLE_360) - sub2_view_right;
- }
- else
- {
- buffer_check = relative_angle - sub2_view_right; // Calc. view column of object
- }
-
-
- // if ((buffer_check < ANGLE_0) || (buffer_check > ANGLE_60)) return;
- if (buffer_check < ANGLE_0)
- scale=(int)(cos_table[ANGLE_0]/(sprite_dist))>>1;
- else
- if (buffer_check > VIEW_CONE)
- scale=(int)(cos_table[VIEW_CONE]/(sprite_dist))>>1;
- else
- scale=(int)(cos_table[buffer_check]/(sprite_dist))>>1;
-
-
- sprite_width = scale*obj_statistic_list[which_object].width_factor;
-
- scale_factor = (obj_statistic_list[which_object].Scale_Factor)/((fixed)sprite_width);
- planar_scale_factor = scale_factor<<2;
-
- left = COLUMN_OFFSET-(buffer_check);
-
- if (scale>(MAX_SCALE-1))
- scale=(MAX_SCALE-1);
-
- scale_row = scale_table[scale-1];
- scale_column = scale_table[sprite_width-1];
-
- if (scale>(WINDOW_HALF_HEIGHT))
- {
- scale=(WINDOW_HALF_HEIGHT);
- }
-
- sliver_scale = scale-1;
-
- // set up parameters for assembly language
-
- switch(which_object)
- {
- case 0:
- {
- sliver_texture = ob_frames.frames[0];
- rend_func_ptr = Render_Sliver_Mask;
- }
- break;
-
- case 1:
- {
- sliver_texture = ob_frames.frames[1];
- rend_func_ptr = Render_Sliver_Mask_Special;
- }
- break;
-
- case 2:
- {
- if (enemies[ID_Number].state == FIRING)
- {
- sliver_texture = duck_frames.frames[8];
- }
- else
- if (enemies[ID_Number].state == HIT)
- {
- sliver_texture = duck_frames.frames[10];
- }
- else
- if (enemies[ID_Number].state == DEAD)
- {
- sliver_texture = duck_frames.frames[9];
- }
- else
- if (enemies[ID_Number].state == DYING)
- {
- sliver_texture = duck_death.frames[(7-threshold)/2];
-
- what_half = (7-threshold) % 2;
- }
- else
- {
- pquad = (relative_angle+ANGLE_23)/angles_per_side;
- oquad = (object_angle+ANGLE_23)/angles_per_side;
- j = (pquad - oquad)+(sides_per_object>>1);
-
- if (j >= sides_per_object)
- j -= sides_per_object;
-
- if (j < 0)
- j += sides_per_object;
-
- sliver_texture = duck_frames.frames[j];
-
- }
-
- rend_func_ptr = Render_Sliver_Mask_Just_Bottom;
-
- }
- break;
-
- case 3:
- {
- if (enemies[ID_Number].state == FIRING)
- {
- sliver_texture = duck_frames.frames[8];
- }
- else
- if (enemies[ID_Number].state == HIT)
- {
- sliver_texture = duck_frames.frames[10];
- }
- else
- if (enemies[ID_Number].state == DEAD)
- {
- sliver_texture = duck_frames.frames[9];
- }
- else
- if (enemies[ID_Number].state == DYING)
- {
- sliver_texture = duck_death.frames[(7-threshold)/2];
-
- what_half = (7-threshold) % 2;
- }
- else
- {
- pquad = (relative_angle+ANGLE_23)/angles_per_side;
- oquad = (object_angle+ANGLE_23)/angles_per_side;
- j = (pquad - oquad)+(sides_per_object>>1);
-
- if (j >= sides_per_object)
- j -= sides_per_object;
-
- if (j < 0)
- j += sides_per_object;
-
- sliver_texture = duck_frames.frames[j];
-
- }
-
- rend_func_ptr = Render_UpsideDwn_Mask_Bottom;
- }
- break;
-
-
- case 4:
- {
- sliver_texture = ob_frames.frames[2];
- rend_func_ptr = Render_Sliver_Mask_Just_Bottom;
- }
- break;
-
- case 5:
- {
- sliver_texture = ob_frames.frames[3];
- rend_func_ptr = Render_Sliver_Mask_Just_Bottom;
- }
- break;
-
- case 6:
- {
- sliver_texture = ob_frames.frames[4];
- rend_func_ptr = Render_Sliver_Mask_Just_Bottom;
- }
- break;
-
- }
-
- sprite_left = left+(sprite_width>>1);
- sprite_right = sprite_left-sprite_width;
-
- sliver_column = 0;
-
- adjusted_index = 0;
- sliver_top = WINDOW_MIDDLE - (scale >> 1);
-
- buffer_check = buffer_check - (sprite_width>>1);
-
- temp_buffer_check = buffer_check;
-
- _asm
- {
- mov dx,SEQUENCER // address the sequencer
- mov al,SEQ_PLANE_ENABLE // select the plane enable register
- mov cl,BYTE PTR sprite_left // extract lower byte from x
- and cl,03h // extract the plane number = x MOD 4
- mov ah,1 // a "1" selects the plane in the plane enable
- shl ah,cl // shift the "1" bit proper number of times
- out dx,ax // do it baby!
- }
-
- for (sprite_index = sprite_left; sprite_index > sprite_right; sprite_index-=4)
- {
- if ((temp_buffer_check >= ANGLE_0) && (temp_buffer_check < VIEW_CONE))
- {
- if (sprite_dist < vz_buffer[temp_buffer_check])
- {
-
- sliver_column = (what_half<<5) + adjusted_index>>16;
-
- sliver_ray = sprite_index;
-
- // render the sliver in assembly
-
- (*rend_func_ptr) ();
- }
- }
-
- temp_buffer_check+=4;
- adjusted_index+=planar_scale_factor;
- }
-
- temp_buffer_check = buffer_check+1;
- sprite_left -= 1;
- adjusted_index = scale_factor;
-
- _asm
- {
- mov dx,SEQUENCER // address the sequencer
- mov al,SEQ_PLANE_ENABLE // select the plane enable register
- mov cl,BYTE PTR sprite_left // extract lower byte from x
- and cl,03h // extract the plane number = x MOD 4
- mov ah,1 // a "1" selects the plane in the plane enable
- shl ah,cl // shift the "1" bit proper number of times
- out dx,ax // do it baby!
- }
-
- for (sprite_index = sprite_left; sprite_index > sprite_right; sprite_index-=4)
- {
- if ((temp_buffer_check >= ANGLE_0) && (temp_buffer_check < VIEW_CONE))
- {
- if (sprite_dist < vz_buffer[temp_buffer_check])
- {
-
- sliver_column = (what_half<<5) + adjusted_index>>16;
-
- sliver_ray = sprite_index;
-
- // render the sliver in assembly
-
- (*rend_func_ptr) ();
- }
- }
-
- temp_buffer_check+=4;
- adjusted_index+=planar_scale_factor;
- }
-
- temp_buffer_check = buffer_check+2;
- sprite_left -= 1;
- adjusted_index = scale_factor<<1;
-
- _asm
- {
- mov dx,SEQUENCER // address the sequencer
- mov al,SEQ_PLANE_ENABLE // select the plane enable register
- mov cl,BYTE PTR sprite_left // extract lower byte from x
- and cl,03h // extract the plane number = x MOD 4
- mov ah,1 // a "1" selects the plane in the plane enable
- shl ah,cl // shift the "1" bit proper number of times
- out dx,ax // do it baby!
- }
-
- for (sprite_index = sprite_left; sprite_index > sprite_right; sprite_index-=4)
- {
- if ((temp_buffer_check >= ANGLE_0) && (temp_buffer_check < VIEW_CONE))
- {
- if (sprite_dist < vz_buffer[temp_buffer_check])
- {
-
- sliver_column = (what_half<<5) + adjusted_index>>16;
-
- sliver_ray = sprite_index;
-
- // render the sliver in assembly
-
- (*rend_func_ptr) ();
- }
- }
-
- temp_buffer_check+=4;
- adjusted_index+=planar_scale_factor;
- }
-
- temp_buffer_check = buffer_check+3;
- sprite_left -= 1;
- adjusted_index = scale_factor<<1;
- adjusted_index += scale_factor;
-
- _asm
- {
- mov dx,SEQUENCER // address the sequencer
- mov al,SEQ_PLANE_ENABLE // select the plane enable register
- mov cl,BYTE PTR sprite_left // extract lower byte from x
- and cl,03h // extract the plane number = x MOD 4
- mov ah,1 // a "1" selects the plane in the plane enable
- shl ah,cl // shift the "1" bit proper number of times
- out dx,ax // do it baby!
- }
-
- for (sprite_index = sprite_left; sprite_index > sprite_right; sprite_index-=4)
- {
- if ((temp_buffer_check >= ANGLE_0) && (temp_buffer_check < VIEW_CONE))
- {
- if (sprite_dist < vz_buffer[temp_buffer_check])
- {
-
- sliver_column = (what_half<<5) + adjusted_index>>16;
-
- sliver_ray = sprite_index;
-
- // render the sliver in assembly
-
- (*rend_func_ptr) ();
- }
- }
-
- temp_buffer_check+=4;
- adjusted_index+=planar_scale_factor;
- }
-
-
- } // END FIND AND MAYBE PLOT OBJECTS
-
- void Make_Light_Metallic_Blue_Palette(void)
- {
- // this function generates 64 shades of Light_Metallic_Blue and places them in the palette
- // at locations 16 to 80
-
- int index;
-
- RGB_color color;
-
- // generate 64 shades of Light_Metallic_Blue
-
- for (index = 0; index < 40; index++)
- {
- color.red = 0;
- color.green = index;
- color.blue = index;
-
- old_all[16+index] = color;
-
- // write the color in the palette starting at location 16, so as not to
- // fry the EGA palette
-
- Write_Color_Reg(16+index,(RGB_color_ptr)&color);
- }
- } // end Make_Light_Metallic_Blue_Palette
-
- void Make_Gold_Palette(void)
- {
- // this function generates 64 shades of gold and places them in the palette
- // at locations 16 to 80
-
- int index;
-
- RGB_color color;
-
- // generate 64 shades of gold
-
- for (index = 0; index < 40; index++)
- {
- color.red = index;
- color.green = index;
- color.blue = 0;
-
- old_all[16+index] = color;
-
- // write the color in the palette starting at location 16, so as not to
- // fry the EGA palette
-
- Write_Color_Reg(16+index,(RGB_color_ptr)&color);
- }
- } // end Make_Gold_Palette
-
- void Make_Gray_Palette(void)
- {
- // this function generates 64 shades of gray and places them in the palette
- // at locations 16 to 80
-
- int index;
-
- RGB_color color;
-
- // generate 64 shades of gray
-
- for (index = 0; index < 40; index++)
- {
- color.red = index;
- color.green = index;
- color.blue = index;
-
- old_all[16+index] = color;
-
- // write the color in the palette starting at location 16, so as not to
- // fry the EGA palette
-
- Write_Color_Reg(16+index,(RGB_color_ptr)&color);
- }
- } // end Make_Gold_Palette
-
- void Make_Blue_Palette(void)
- {
- // this function generates 64 shades of gray and places them in the palette
- // at locations 16 to 80
-
- int index;
-
- RGB_color color;
-
- // generate 64 shades of gray
-
- for (index = 0; index < 64; index++)
- {
- color.red = 0;
- color.green = 0;
- color.blue = index;
-
- old_all[16+index] = color;
-
- // write the color in the palette starting at location 16, so as not to
- // fry the EGA palette
-
- Write_Color_Reg(16+index,(RGB_color_ptr)&color);
- }
- } // end Make_Gold_Palette
-
- void Make_Gray_Palette_OAAT(int delta, int erase_trail)
- {
- // this function generates 64 shades of gray and places them in the palette
- // at locations 16 to 80
-
- int index;
-
- RGB_color color;
-
- // generate 64 shades of gray
-
- index = delta;
-
- color.red = index;
- color.green = index;
- color.blue = index;
-
- old_all[16+index] = color;
-
- // write the color in the palette starting at location 16, so as not to
- // fry the EGA palette
-
- Write_Color_Reg(16+index,(RGB_color_ptr)&color);
-
- } // end Make_Gray_Palette_OAAT
-
- void Make_Blue_Palette_OAAT(int delta, int erase_trail)
- {
- // this function generates 64 shades of gray and places them in the palette
- // at locations 16 to 80
-
- int index;
-
- RGB_color color;
-
- // generate 64 shades of gray
-
- index = delta;
-
- // gray equals equal percentage of Red, Green and Blue
-
- if (index!=39)
- {
- color.red = 0;
- color.green = 0;
- color.blue = index;
-
- old_all[16+index] = color;
-
- // write the color in the palette starting at location 16, so as not to
- // fry the EGA palette
-
- Write_Color_Reg(16+index,(RGB_color_ptr)&color);
- }
-
- if ((index!=0) && (erase_trail))
- {
- --index;
-
- color.red = index;
- color.green = index;
- color.blue = index;
-
- old_all[16+index] = color;
-
- // write the color in the palette starting at location 16, so as not to
- // fry the EGA palette
-
- Write_Color_Reg(16+index,(RGB_color_ptr)&color);
-
- }
-
- } // end Make_Blue_Palette_OAAT
-
- void Make_Gold_Palette_OAAT(int delta, int erase_trail)
- {
- // this function generates 64 shades of gray and places them in the palette
- // at locations 16 to 80
-
- int index;
-
- RGB_color color;
-
- // generate 64 shades of gray
-
- index = delta;
-
- if (index!=39)
- {
- // gray equals equal percentage of Red, Green and Blue
-
- color.red = 0;
- color.green = index;
- color.blue = index;
-
- old_all[16+index] = color;
-
- // write the color in the palette starting at location 16, so as not to
- // fry the EGA palette
-
- Write_Color_Reg(16+index,(RGB_color_ptr)&color);
- }
-
- if ((index!=0) && (erase_trail))
- {
- --index;
-
- color.red = index;
- color.green = index;
- color.blue = index;
-
- old_all[16+index] = color;
-
- // write the color in the palette starting at location 16, so as not to
- // fry the EGA palette
-
- Write_Color_Reg(16+index,(RGB_color_ptr)&color);
-
- }
-
- } // end Make_Gold_Palette_OAAT
-
- void Make_Cyan_Palette_OAAT(int delta, int erase_trail)
- {
- // this function generates 64 shades of gray and places them in the palette
- // at locations 16 to 80
-
- int index;
-
- RGB_color color;
-
- index = delta;
- // generate 64 shades of gray
- if (index!=39)
- {
-
- // gray equals equal percentage of Red, Green and Blue
-
- color.red = index;
- color.green = index;
- color.blue = 0;
-
- old_all[16+index] = color;
-
- // write the color in the palette starting at location 16, so as not to
- // fry the EGA palette
-
- Write_Color_Reg(16+index,(RGB_color_ptr)&color);
- }
-
- if ((index!=0) && (erase_trail))
- {
- --index;
-
- color.red = index;
- color.green = index;
- color.blue = index;
-
- old_all[16+index] = color;
-
- // write the color in the palette starting at location 16, so as not to
- // fry the EGA palette
-
- Write_Color_Reg(16+index,(RGB_color_ptr)&color);
-
- }
-
- } // end Make_Cyan_Palette_OAAT
-
-
- void Process_Doors(void)
- {
- // Checks the list of doors, and processes them if they are
- // OPENING, OPEN, OR CLOSING
-
- int cells_x,cells_y,row,column;
- int index = total_world_doors;
- int enem_index;
- int in_the_doorway = 0;
- int x_player,y_player;
- int x_cell_d,y_cell_d;
- int processed_doors;
-
- // you might want to put the active doors in a linked list...
- // but I did it this way, because there aren't many doors per map
- // ALOT OF THE THINGS I DO HERE ARE DOPEY!
-
- for (index = 0; index < total_world_doors; index++)
- {
- // get the x & y map coordinates for the door
-
- x_cell_d = doors[index].door_x;
- y_cell_d = doors[index].door_y;
-
- if (doors[index].door_state != CLOSED)
- {
- if (doors[index].door_state == OPENING)
- {
- // open the door some more...
-
- doors[index].door_increment+=6;
-
- // when the door is all the way open - STOP OPENING IT!
-
- if (doors[index].door_increment > 64)
- {
- // this holds the door open a little while...
-
- doors[index].door_wait_to_close = 80;
-
- // this simply ensures the door is set open
-
- doors[index].door_increment = 64;
-
- // Take the door out of the world map... so that
- // the rendering engine can ignore it completely
- // (not the smartest way...)
-
- world[y_cell_d][x_cell_d].block_type = 0;
-
- // Allow the player to pass through the vacant doorway
-
- Block_Map[y_cell_d][x_cell_d] = 0;
-
- // set door state to OPEN
-
- doors[index].door_state = OPEN;
- }
- }
- else
- if (doors[index].door_state == CLOSING)
- {
- // close the door some more...
-
- doors[index].door_increment-=6;
-
- if (doors[index].door_increment < 0) // is it all the way
- { // closed?
- doors[index].door_state = CLOSED;
- doors[index].door_increment = 0;
- }
- }
- else
- if (doors[index].door_state == OPEN)
- {
- doors[index].door_wait_to_close--; // countdown to closing...
-
- if (doors[index].door_wait_to_close < 0)
- {
- in_the_doorway = 0;
-
- x_player = x / CELL_X_SIZE;
- y_player = y / CELL_Y_SIZE;
-
- // is the player in the doorway?
-
- if ((y_player == (y_cell_d)) && // NOPE!
- (x_player == x_cell_d))
- in_the_doorway = 1;
-
- if (!in_the_doorway)
- {
- for (enem_index=0; enem_index <= Number_Of_Enemies; enem_index++)
- {
- if(!in_the_doorway)
- {
- x_player = enemies[enem_index].vitals.x / CELL_X_SIZE;
- y_player = enemies[enem_index].vitals.y / CELL_Y_SIZE;
-
- if ((y_player == (y_cell_d)) && // NOPE!
- (x_player == x_cell_d))
- in_the_doorway = 1;
- }
- }
- }
-
- if (!in_the_doorway)
- {
- // put door back into the world map
-
- world[y_cell_d][x_cell_d].block_type=
- doors[index].door_block_type;
-
- // make block impassable
-
- Block_Map[y_cell_d][x_cell_d] = 1;
-
- // the door is closing
-
- doors[index].door_state = CLOSING;
- doors[index].door_wait_to_close = 0;
- }
- else
- {
- doors[index].door_state = OPEN;
- doors[index].door_wait_to_close = 10;
- }
- }
- }
- }
- } // end while
-
- } // end Process_Doors
-
-
- void Create_Scale_Data(int scaler, int *row)
- {
-
- // this function synthesizes the scaling of a texture sliver to all possible
- // sizes and creates a huge look up table of the data.
-
- int y_off;
-
- float y_scale_index=0,
- y_scale_step;
-
- // compute scale step or number of source pixels to map to destination/cycle
-
- y_scale_step = (float)32/(float)scaler;
-
- y_scale_index+=y_scale_step;
-
- for (y_off=0; y_off<scaler; y_off++)
- {
- // place data into proper array position for later use
-
- row[y_off] = ((int)(y_scale_index+.4)) * SWATCH_WIDTH;
-
- // test if we slightly went overboard
-
- if (row[y_off] > WALL_MIDDLE_OFFSET) row[y_off] = WALL_MIDDLE_OFFSET;
-
- // next index please
-
- y_scale_index+=y_scale_step;
-
- } // end for y_off
-
- } // end Create_Scale_Data
-
- void Create_Scale_Data2(int scaler, int *row)
- {
-
- // this function synthesizes the scaling of a texture sliver to all possible
- // sizes and creates a huge look up table of the data.
-
- // this adds data for cases where the vertical extents of the "sliver" are
- // beyond the vertical extents of the viewport
-
- int y_off;
-
- float y_scale_index=0,
- y_scale_step;
-
- // compute scale step or number of source pixels to map to destination/cycle
-
- y_scale_step = (float)32/(float)scaler;
-
- y_scale_index+=y_scale_step;
-
- for (y_off=0; y_off<WINDOW_HALF_HEIGHT+1; y_off++)
- {
- // place data into proper array position for later use
-
- row[y_off] = ((int)(y_scale_index+.4)) * SWATCH_WIDTH;
-
- // test if we slightly went overboard
-
- if (row[y_off] > WALL_MIDDLE_OFFSET) row[y_off] = WALL_MIDDLE_OFFSET;
-
- // next index please
-
- y_scale_index+=y_scale_step;
-
- } // end for y_off
-
- } // end Create_Scale_Data2
-
- void Build_Tables(void)
- {
-
- // this function builds all the look up tables for the system
-
- // the ANGLE_?s are assigned values here because I wanted to make the
- // viewport resizable(!?) (probably not the best way)
-
- int ang,scale;
- float rad_angle;
-
- ANGLE_360= my_size;
-
- ANGLE_180= (ANGLE_360>>1);
- ANGLE_90= (ANGLE_360>>2);
- ANGLE_75= (ANGLE_360/4.8);
- ANGLE_60= (ANGLE_360/6);
- ANGLE_45= (ANGLE_360/8);
- ANGLE_30= (ANGLE_360/12);
- ANGLE_15= (ANGLE_360/24);
- ANGLE_6= (ANGLE_360/60);
- ANGLE_5= (ANGLE_360/72);
- ANGLE_4= (ANGLE_360/90);
- ANGLE_2= (ANGLE_360/180);
- ANGLE_1= (ANGLE_360/360);
- ANGLE_0= 0;
-
- // some ODDBALL angles
-
- ANGLE_315= (ANGLE_360-ANGLE_45);
- ANGLE_270= (ANGLE_360-ANGLE_90);
- ANGLE_225= (ANGLE_270-ANGLE_45);
- ANGLE_135= (ANGLE_180-ANGLE_45);
- ANGLE_10= (ANGLE_5+ANGLE_5);
- ANGLE_9= (ANGLE_5+ANGLE_4);
- ANGLE_8= (ANGLE_4+ANGLE_4);
- ANGLE_7= (ANGLE_8-ANGLE_1);
- //... and some possible 'view cones'...
- ANGLE_80 = (ANGLE_90-ANGLE_10);
- ANGLE_70 = (ANGLE_60+ANGLE_10);
-
- // for 'shifting the parachute' (?!)
-
- ANGLE_23= (ANGLE_15 + ANGLE_5 + ANGLE_2 + ANGLE_1);
-
- // VIEW CONE VALUES...
-
- VIEW_CONE = ANGLE_90;
- HALF_VIEW_CONE = (VIEW_CONE>>1);
-
- // conversion constants from radians to degrees and vice-versa
-
- ANGULAR_INCREMENT =((float)360/(float)ANGLE_360);
- RAD_TO_DEG = (((float)180/(float)ANGULAR_INCREMENT)/(float)3.1415926);
-
- WINDOW_HEIGHT= my_height;
-
- WINDOW_HALF_HEIGHT= (WINDOW_HEIGHT>>1);
-
- WINDOW_MIDDLE= 79;
-
- WINDOW_MIDDLE_MINUS= 78;
-
- WINDOW_TOP= WINDOW_MIDDLE-WINDOW_HALF_HEIGHT+1;
- WINDOW_BOTTOM= WINDOW_MIDDLE+WINDOW_HALF_HEIGHT-1;
- WINDOW_LEFT= my_left;
- WINDOW_RIGHT= my_right;
-
- VERTICAL_SCALE= my_v_scale; // used to scale the "slivers" to get proper
-
- // allocate memory for all look up tables
-
- // tangent tables equivalent to slopes
-
- tan_table = (float far *)_fmalloc(sizeof(float) * (ANGLE_360+1) );
- inv_tan_table = (float far *)_fmalloc(sizeof(float) * (ANGLE_360+1) );
-
- // step tables used to find next intersections, equivalent to slopes
- // times width and height of cell
-
- y_step = (float far *)_fmalloc(sizeof(float) * (ANGLE_360+1) );
- x_step = (float far *)_fmalloc(sizeof(float) * (ANGLE_360+1) );
-
-
- // cos table used to fix view distortion caused by caused by radial projection
-
- cos_table = (float far *)_fmalloc(sizeof(float) * (VIEW_CONE+1) );
-
-
- // 1/cos and 1/sin tables used to compute distance of intersection very
- // quickly
-
- inv_cos_table = (float far *)_fmalloc(sizeof(float) * (ANGLE_360+1) );
- inv_sin_table = (float far *)_fmalloc(sizeof(float) * (ANGLE_360+1) );
-
- // create the lookup tables for the scaler
- // there have the form of an array of pointers, where each pointer points
- // another another array of data where the 'data' are the scale indices
-
- for (scale=0; scale<=WINDOW_HALF_HEIGHT; scale++)
- {
-
- scale_table[scale] = (int *)malloc(scale*sizeof(int)+1);
-
- } // end for scale
- for (scale=WINDOW_HALF_HEIGHT+1; scale<=MAX_SCALE; scale++)
- {
-
- scale_table[scale] = (int *)malloc((WINDOW_HALF_HEIGHT+1)*sizeof(int)+1);
-
- } // end for scale
-
- // create tables, sit back for a sec!
-
- for (ang=ANGLE_0; ang<=ANGLE_360; ang++)
- {
-
- rad_angle = (float)((3.272e-4) + ang * 2*3.141592654/ANGLE_360);
-
- tan_table[ang] = (float)tan(rad_angle);
- inv_tan_table[ang] = (float)(1/tan_table[ang]);
-
-
- // tangent has the incorrect signs in all quadrants except 1, so
- // manually fix the signs of each quadrant since the tangent is
- // equivalent to the slope of a line and if the tangent is wrong
- // then the ray that is case will be wrong
-
- if (ang>=ANGLE_0 && ang<ANGLE_180)
- {
- y_step[ang] = (float)(fabs(tan_table[ang] * CELL_Y_SIZE));
- }
- else
- y_step[ang] = (float)(-fabs(tan_table[ang] * CELL_Y_SIZE));
-
- if (ang>=ANGLE_90 && ang<ANGLE_270)
- {
- x_step[ang] = (float)(-fabs(inv_tan_table[ang] * CELL_X_SIZE));
- }
- else
- {
- x_step[ang] = (float)(fabs(inv_tan_table[ang] * CELL_X_SIZE));
- }
-
-
- // create the sin and cosine tables to copute distances
-
- inv_cos_table[ang] = (float)(1/cos(rad_angle));
- inv_sin_table[ang] = (float)(1/sin(rad_angle));
-
- } // end for ang
-
- ///////////////////////////////////////////////////////
-
- // THE FOLLOWING LINES ARE THE FOSSILIZED REMAINS OF WHAT I NEED TO
- // DO WHEN I IMPLEMENTED FIXED POINT MATH, W/ LONG INTEGERS FOR VALUES
- // IN THE LOOKUP TABLES
-
- ///////////////////////////////////////////////////////
-
- tan_table[ANGLE_0] = tan_table[ANGLE_0+1];
- inv_tan_table[ANGLE_0] = inv_tan_table[ANGLE_0+1];
- tan_table[ANGLE_90] = tan_table[ANGLE_90+1];
- inv_tan_table[ANGLE_90] = inv_tan_table[ANGLE_90+1];
- tan_table[ANGLE_180] = tan_table[ANGLE_180+1];
- inv_tan_table[ANGLE_180] = inv_tan_table[ANGLE_180+1];
- tan_table[ANGLE_270] = tan_table[ANGLE_270+1];
- inv_tan_table[ANGLE_270] = inv_tan_table[ANGLE_270+1];
-
- y_step[ANGLE_0] = y_step[ANGLE_0+1];
- x_step[ANGLE_0] = x_step[ANGLE_0+1];
- y_step[ANGLE_90] = y_step[ANGLE_90+1];
- x_step[ANGLE_90] = x_step[ANGLE_90+1];
- y_step[ANGLE_180] = y_step[ANGLE_180+1];
- x_step[ANGLE_180] = x_step[ANGLE_180+1];
- y_step[ANGLE_270] = y_step[ANGLE_270+1];
- x_step[ANGLE_270] = x_step[ANGLE_270+1];
-
- // create the sin and cosine tables to copute distances
-
- inv_cos_table[ANGLE_0] = inv_cos_table[ANGLE_0+1];
- inv_sin_table[ANGLE_0] = inv_sin_table[ANGLE_0+1];
- inv_cos_table[ANGLE_90] = inv_cos_table[ANGLE_90+1];
- inv_sin_table[ANGLE_90] = inv_sin_table[ANGLE_90+1];
- inv_cos_table[ANGLE_180] = inv_cos_table[ANGLE_180+1];
- inv_sin_table[ANGLE_180] = inv_sin_table[ANGLE_180+1];
- inv_cos_table[ANGLE_270] = inv_cos_table[ANGLE_270+1];
- inv_sin_table[ANGLE_270] = inv_sin_table[ANGLE_270+1];
-
- // create view filter table. There is a cosine wave modulated on top of
- // the view distance as a side effect of casting from a fixed point.
- // to cancel this effect out, we multiple by the inverse of the cosine
- // and the result is the proper scale. Without this we would see a
- // fishbowl effect, which might be desired in some cases?
-
- for (ang=(-HALF_VIEW_CONE); ang<=(HALF_VIEW_CONE); ang++)
- {
-
- rad_angle = (float)((3.272e-4) + ang * 2*3.141592654/ANGLE_360);
-
- cos_table[ang+HALF_VIEW_CONE] = (float)(VERTICAL_SCALE/cos(rad_angle));
-
- } // end for
-
- // build the scaler table. This table holds MAX_SCALE different arrays. Each
- // array consists of the pre-computed indices for an object to be scaled
-
- for (scale=1; scale<=WINDOW_HALF_HEIGHT; scale++)
- {
-
- // create the indices for this scale
-
- Create_Scale_Data(scale, (int *)scale_table[scale]);
-
- } // end for scale
-
- // THE SECOND Create_Scale_Data FUNCTION REFERED TO HERE IS USED
- // TO COMPUTE SCALES FOR CASES WHERE THE BOTTOM AND THE TOP OF A WALL
- // SLIVER ARE BEYOND THE VERTICAL EXTENTS OF THE VIEWPORT!
-
- for (scale=WINDOW_HALF_HEIGHT+1; scale<=MAX_SCALE; scale++)
- {
-
- // create the indices for this scale
-
- Create_Scale_Data2(scale, (int *)scale_table[scale]);
-
- } // end for scale
-
- // I saved a few multiplies with these...
-
- for (ang = 0; ang<200; ang++)
- v_320[ang] = ang*320;
-
- for (ang = 0; ang<200; ang++)
- v_80[ang] = ang*80;
-
- for (ang = 0; ang<320; ang++)
- h_320[ang] = ang>>2;
-
- } // end Build_Tables
-
- /////////////////////////////////////////////////////////////////////////////
-
- void Allocate_World(void)
- {
- // this function allocates the memory for the world
-
- // I had initially allocated the world[][] array here...
- // ... and believe it or not... even though there are always fewer
- // than say, 15 doors to a map - I allocated a doors[][] array here too.
- // NEEDLESS TO SAY - I WAS VERY WASTEFUL OF RESOURCES
-
- int index;
-
- // allocate each row
-
- for (index=0; index<WORLD_ROWS; index++)
- {
- Block_Map[index] = (char far *)_fmalloc(WORLD_COLUMNS+1);
- } // end for index
-
- } // end Allocate_World
-
-
- ////////////////////////////////////////////////////////////////////////////////
-
- int Load_World(int lev_number)
- {
- // this function opens the input file and loads the world data from it
-
- // the maps for this 'game' are 32x32 text files (you can makem' with
- // notepad). 2s and 3s make doors.
-
- // 4s were used to make impassable, invisible walls (for objects)
-
- FILE *fp, *fopen();
- int ob_num,gunner_num;
-
- int index,row,column;
- char buffer[WORLD_COLUMNS+2],ch;
- int door_num = 0;
- int result;
- long pos;
-
- // open the file
-
- if (!(fp = fopen("world.dat","r")))
- return(0);
-
- pos = (1088L*(long)(lev_number<<1));
- result = fseek( fp, pos, SEEK_SET);
- if( result )
- Print_String_Mode_Y(10,10,79,"Fseek failure",0);
-
- // load in the data
-
- for (row=0; row<WORLD_ROWS; row++)
- {
- // load in the next row
-
- for (column=0; column<WORLD_COLUMNS; column++)
- {
-
- while((ch = getc(fp))==10){} // filter out CR
-
- // translate character to integer
-
- if (ch == ' ')
- ch=0;
- else
- ch = ch - '0';
-
- // insert data into world
-
- if (ch==4)
- world[(WORLD_ROWS-1) - row][column].block_type = 0;
- else
- world[(WORLD_ROWS-1) - row][column].block_type = ch;
-
- Block_Map[(WORLD_ROWS-1) - row][column] = ch;
-
-
- if ((ch == 2) || (ch == 3)) // if it's a door
- {
- world[(WORLD_ROWS-1) - row][column].door_id = door_num;
-
-
- doors[door_num].door_y = (WORLD_ROWS-1) - row;
- doors[door_num].door_x = column;
- doors[door_num].door_state = CLOSED;
- doors[door_num].door_block_type = ch;
- doors[door_num].locked=0;
- doors[door_num].door_speed=5;
- doors[door_num].door_increment=0;
- doors[door_num].door_wait_to_close=0;
-
- door_num++;
- }
- } // end for column
-
- // process the row
-
- } // end for row
-
- total_world_doors = door_num; // used by Process_Doors
-
- // allocate space for object lists...
-
- // init ob counter
-
- ob_num = 0;
- gunner_num = 0;
-
- // load in the data
-
- for (row=0; row<WORLD_ROWS; row++)
- {
- // load in the next row
-
- for (column=0; column<WORLD_COLUMNS; column++)
- {
-
- while((ch = getc(fp))==10){} // filter out CR
-
- // translate character to integer
-
- if ((ch == '0') || (ch == '1') || (ch == '6'))
- {
- ch = ch - '0';
-
- initial_object_list[ob_num].x = (column<<CELL_X_SIZE_FP)+32;
- initial_object_list[ob_num].y = (((WORLD_ROWS-1) - row)<<CELL_Y_SIZE_FP)+32;
- initial_object_list[ob_num].angle = ANGLE_0;
- initial_object_list[ob_num].kind_of_object = ch;
- initial_object_list[ob_num].dist = 0;
-
- ob_num++;
- }
-
-
- } // end for column
-
- // process the row
-
- } // end for row
-
- // close the file
-
- result = fseek( fp, pos+1088L, SEEK_SET);
- if( result )
- Print_String_Mode_Y(10,10,79,"Fseek failure",0);
-
- // load in the data
-
- for (row=0; row<WORLD_ROWS; row++)
- {
- // load in the next row
-
- for (column=0; column<WORLD_COLUMNS; column++)
- {
-
- while((ch = getc(fp))==10){} // filter out CR
-
- // translate character to integer
-
- if ((ch == '4') || (ch == '5'))
- {
- ch = ch - '0';
-
- initial_object_list[ob_num].x = (column<<CELL_X_SIZE_FP)+32;
- initial_object_list[ob_num].y = (((WORLD_ROWS-1) - row)<<CELL_Y_SIZE_FP)+32;
- initial_object_list[ob_num].angle = ANGLE_0;
- initial_object_list[ob_num].kind_of_object = ch;
- initial_object_list[ob_num].dist = 0;
-
- ob_num++;
- }
-
-
- } // end for column
-
- // process the row
-
- } // end for row
-
- // close the file
-
- Number_Of_Fixed_Objects = ob_num;
-
- ob_num = 0;
-
- result = fseek( fp, pos+1088L, SEEK_SET);
- if( result )
- Print_String_Mode_Y(10,10,79,"Fseek failure",0);
-
-
- // load in the data
-
- for (row=0; row<WORLD_ROWS; row++)
- {
- // load in the next row
-
- for (column=0; column<WORLD_COLUMNS; column++)
- {
-
- while((ch = getc(fp))==10){} // filter out CR
-
- // translate character to integer
-
- if ((ch == '2') || (ch == '3'))
- {
- ch = ch - '0';
-
- enemies[ob_num].vitals.x = (column<<CELL_X_SIZE_FP)+32;
- enemies[ob_num].vitals.y = (((WORLD_ROWS-1) - row)<<CELL_Y_SIZE_FP)+32;
- enemies[ob_num].vitals.angle = ANGLE_0;
- enemies[ob_num].vitals.kind_of_object = ch;
- enemies[ob_num].vitals.dist = 0;
- enemies[ob_num].enem_num = ob_num;
-
- enemies[ob_num].state = WAITING;
- enemies[ob_num].threshold = 0;
- enemies[ob_num].hit_points = 5;
- enemies[ob_num].pat_num = 0;
-
- ob_num++;
- }
-
-
- } // end for column
-
- // process the row
-
- } // end for row
-
- // close the file
-
- fclose(fp);
-
- Number_Of_Enemies = ob_num;
-
- // close the file
-
- //return(1);
-
- } // end Load_World
-
- /////////////////////////////////////////////////////////////////////////////
-
- void Ray_Caster(void)
- {
-
- // This is the heart of the system. it casts out 320 rays and builds the
- // 3-D image from their intersections with the walls. It was derived from
- // the previous version used in "RAY.C", however, it has been extremely
- // optimized for speed by the use of many more lookup tables and fixed
- // point math
-
- register int
- curr_ang,
- cell_x, // the current cell that the ray is in
- cell_y,
- ray, // the current ray being cast 0-320
- casting=2, // tracks the progress of the X and Y component of the ray
- x_hit_type, // records the block that was intersected, used to figure
- y_hit_type, // out which texture to use
- x_bound, // the next vertical and horizontal intersection point
- y_bound,
- next_y_cell, // used to figure out the quadrant of the ray
- next_x_cell,
- xray=0, // tracks the progress of a ray looking for Y interesctions
- yray=0, // tracks the progress of a ray looking for X interesctions
-
- x_delta, // the amount needed to move to get to the next cell
- y_delta, // position
- xb_save,
- yb_save,
- xi_save, // used to save exact x and y intersection points
- yi_save,
- scale;
-
- int x_anded,y_anded;
-
- int door_sliver;
-
- int in_bounds;
-
- register long
- cast=0,
- dist_x, // the distance of the x and y ray intersections from
- dist_y; // the viewpoint
-
- register float xi, // used to track the x and y intersections
- yi;
-
- int temp_ray;
-
- int a_toggle, b_toggle;
-
- // variables to handle a door being partially open (one of many ways to do this)
-
- int dor_y_inc=0;
- int dor_x_inc=0;
-
- int doorx_num, doory_num;
-
-
- // S E C T I O N 1 /////////////////////////////////////////////////////////v
-
- // initialization
-
- // compute starting angle from player. Field of view is 90 degrees, so
- // subtract half of that current view angle
-
- // start the current angle off -45 degrees to the left of the player's
- // current viewing direction
-
- // The following inline assembly instructions determine which
- // plane(s) pixels will be written to.
-
- // The value moved into AH (1-15... or 0001 - 1111{binary})
- // determines the plane enabled!
-
- // P L A N E # ? ////////////////////////////////////////////////////
- /////////////////////// E N A B L E D ////////////////////////////////////
-
- // NOTE: I DECIDED TO DO THIS OUTSIDE OF THE RAY-CASTER! /////////////
- // In the procedure Draw_Walls /////////////////////////////
-
- curr_ang = view_angle;
-
- if ( (curr_ang-=HALF_VIEW_CONE) < 0)
- {
- curr_ang=ANGLE_360 + curr_ang;
- } // end if
-
- // loop through all 320 rays
-
- x_anded = (int)(x & 0xffc0);
- y_anded = (int)(y & 0xffc0);
-
- for (ray=0; ray<(VIEW_CONE); ray++)
- {
-
- // S E C T I O N 2 /////////////////////////////////////////////////////////
-
- dor_y_inc=0;
- dor_x_inc=0;
-
- temp_ray = ray;
-
- // compute first x intersection
-
- // need to know which half plane we are casting from relative to Y axis
-
- y_bound = y_anded;
- y_delta = -CELL_Y_SIZE;
- next_y_cell = -1;
- a_toggle = 0;
-
- if (curr_ang >= ANGLE_0 && curr_ang < ANGLE_180)
- {
-
- // compute first horizontal line that could be intersected with ray
- // note: it will be above player
-
- y_bound = (CELL_Y_SIZE + y_anded);
-
- // compute delta to get to next horizontal line
-
- y_delta = CELL_Y_SIZE;
-
- // set cell delta
-
- next_y_cell = 0;
-
- a_toggle = 1;
-
- } // end if upper half plane
-
- // based on first possible horizontal intersection line, compute X
- // intercept, so that casting can begin
-
- xi = inv_tan_table[curr_ang] * (y_bound - y) + x;
-
- // S E C T I O N 3 /////////////////////////////////////////////////////////
-
- // compute first y intersection
-
- x_bound = x_anded;
- x_delta = -CELL_X_SIZE;
-
- next_x_cell = -1;
-
- b_toggle = 0;
- // need to know which half plane we are casting from relative to X axis
-
- if (curr_ang < ANGLE_90 || curr_ang >= ANGLE_270)
- {
-
- // compute first vertical line that could be intersected with ray
- // note: it will be to the right of player
-
- x_bound = (int)(CELL_X_SIZE + x_anded);
-
- // compute delta to get to next vertical line
-
- x_delta = CELL_X_SIZE;
-
- // set cell delta
-
- next_x_cell = 0;
-
- b_toggle = 1;
- } // end if right half plane
-
- // based on first possible vertical intersection line, compute Y
- // intercept, so that casting can begin
-
- yi = tan_table[curr_ang] * (x_bound - x) + y;
-
-
- // begin cast
-
- xray=yray = 0; // reset intersection flags
-
- // PREAMBLE TO S E C T I O N 4 /////////////////////////////////////////////////////////
-
- cell_x = ( (x_bound+next_x_cell) >> CELL_X_SIZE_FP);
-
- cell_y = (int)yi;
- cell_y>>=CELL_Y_SIZE_FP;
-
- // test if there is a block where the current x ray is intersecting
-
- if ((x_hit_type = world[cell_y][cell_x].block_type)!=0)
- {
- if (x_hit_type == 2) // is this an East/West door?
- {
- // get the door's identification number
-
- doorx_num = world[cell_y][cell_x].door_id;
-
- // move the ray a half step forward
-
- yi += y_step[curr_ang]/2;
-
- // what column of the door's bitmap would we use?
-
- door_sliver = ((int)yi & 0x003f);
-
- if (doors[doorx_num].door_state!=CLOSED)
- {
- // if door isn't closed...
- // slide the texture over to the right...
-
- dor_x_inc = door_sliver + doors[doorx_num].door_increment;
-
- if (dor_x_inc > 63) // the door isn't blocking
- { // this ray from a wall beyond...
- //back the ray up a half step
-
- yi -= y_step[curr_ang]/2;
- }
- else
- {
- // confirmed: Door hit
-
- x_hit_type = 3;
-
- xray = INTERSECTION_FOUND;
- }
- }
- else
- {
- // confirmed: Door hit
-
- x_hit_type = 3;
- dor_x_inc = door_sliver;
- xray = INTERSECTION_FOUND;
- }
- }
- else
- xray = INTERSECTION_FOUND;
- } // end if a hit
-
- // S E C T I O N 4 /////////////////////////////////////////////////////////
-
- while(xray!=INTERSECTION_FOUND)
- {
-
- // continue casting each ray in parallel
-
- yi += y_step[curr_ang];
-
- // find next possible x intercept point
-
- x_bound += x_delta;
-
- // compute current map position to inspect
-
- cell_x = ( (x_bound+next_x_cell) >> CELL_X_SIZE_FP);
-
- cell_y = (int)yi;
- cell_y>>=CELL_Y_SIZE_FP;
-
- // test if there is a block where the current x ray is intersecting
-
- if ((x_hit_type = world[cell_y][cell_x].block_type)!=0)
- {
- if (x_hit_type == 2) // is this an East/West door?
- {
- // get the door's identification number
-
- doorx_num = world[cell_y][cell_x].door_id;
-
- // move the ray a half step forward
-
- yi += y_step[curr_ang]/2;
-
- // what column of the door's bitmap would we use?
-
- door_sliver = ((int)yi & 0x003f);
-
- if (doors[doorx_num].door_state!=CLOSED)
- {
- // if door isn't closed...
- // slide the texture over to the right...
-
- dor_x_inc = door_sliver + doors[doorx_num].door_increment;
-
- if (dor_x_inc > 63) // the door isn't blocking
- { // this ray from a wall beyond...
- //back the ray up a half step
-
- yi -= y_step[curr_ang]/2;
- }
- else
- {
- // confirmed: Door hit
-
- x_hit_type = 3;
-
- xray = INTERSECTION_FOUND;
- }
- }
- else
- {
- // confirmed: Door hit
-
- x_hit_type = 3;
- dor_x_inc = door_sliver;
- xray = INTERSECTION_FOUND;
- }
- }
- else
- xray = INTERSECTION_FOUND;
- } // end if a hit
-
- } // end if x ray has intersected
-
- dist_x = (long)((yi - y) * inv_sin_table[curr_ang]);
- yi_save = (int)yi; // what column of the wall (or door's) bitmap
- // do we use.
-
- xb_save = x_bound;
-
- // PREAMBLE TO S E C T I O N 5 /////////////////////////////////////////////////////////
-
- cell_x = xi;
- cell_x>>=CELL_X_SIZE_FP;
-
- cell_y = ( (y_bound + next_y_cell) >> CELL_Y_SIZE_FP);
-
- // test if there is a block where the current y ray is intersecting
-
- if ((y_hit_type = world[cell_y][cell_x].block_type)!=0)
- {
- if (y_hit_type == 3) // is this a north/south doorway?
- {
- // extract door identification #
-
- doory_num = world[cell_y][cell_x].door_id;
-
- // move forward a half step
-
- xi += x_step[curr_ang]/2;
-
- // what column of the door are we looking at?
-
- door_sliver = ((int)xi & 0x003f);
-
- if (doors[doory_num].door_state!=CLOSED)
- {
- // slide door over...
-
- dor_y_inc = door_sliver + doors[doory_num].door_increment;
-
- // does this ray miss the partially opened door?
-
- if (dor_y_inc > 63) // yep!
- {
- // backup half a step
-
- xi -= x_step[curr_ang]/2;
- }
- else
- {
- // it's a hit!
-
- y_hit_type = 3;
- yray = INTERSECTION_FOUND;
- }
- }
- else
- {
- // it's a hit!
-
- dor_y_inc = door_sliver;
- yray = INTERSECTION_FOUND;
- }
- }
- else // not a door... it's a hit!
- yray = INTERSECTION_FOUND;
- }
-
- // S E C T I O N 5 /////////////////////////////////////////////////////////
-
- while (yray!=INTERSECTION_FOUND)
- {
-
- xi += x_step[curr_ang];
-
- // compute next possible y intercept
-
- y_bound += y_delta;
- // compute current map position to inspect
-
- cell_x = xi;
- cell_x>>=CELL_X_SIZE_FP;
-
- cell_y = ( (y_bound + next_y_cell) >> CELL_Y_SIZE_FP);
-
- // test if there is a block where the current y ray is intersecting
-
- if ((y_hit_type = world[cell_y][cell_x].block_type)!=0)
- {
- if (y_hit_type == 3) // is this a north/south doorway?
- {
- // extract door identification #
-
- doory_num = world[cell_y][cell_x].door_id;
-
- // move forward a half step
-
- xi += x_step[curr_ang]/2;
-
- // what column of the door are we looking at?
-
- door_sliver = ((int)xi & 0x003f);
-
- if (doors[doory_num].door_state!=CLOSED)
- {
- // slide door over...
-
- dor_y_inc = door_sliver + doors[doory_num].door_increment;
-
- // does this ray miss the partially opened door?
-
- if (dor_y_inc > 63) // yep!
- {
- // backup half a step
-
- xi -= x_step[curr_ang]/2;
- }
- else
- {
- // it's a hit!
-
- y_hit_type = 3;
- yray = INTERSECTION_FOUND;
- }
- }
- else
- {
- // it's a hit!
-
- dor_y_inc = door_sliver;
- yray = INTERSECTION_FOUND;
- }
- }
- else // not a door... it's a hit!
- yray = INTERSECTION_FOUND;
- }
-
- } // end while not done
-
- dist_y = (long)((xi - x) * inv_cos_table[curr_ang]);
- xi_save = (int)xi;
- yb_save = y_bound;
-
- // S E C T I O N 6 /////////////////////////////////////////////////////////
-
- // at this point, we know that the ray has succesfully hit both a
- // vertical wall and a horizontal wall, so we need to see which one
- // was closer and then render it
-
- if (dist_x < dist_y)
- {
-
- // there was a vertical wall closer than the horizontal
-
- // compute actual scale and multiply by view filter so that spherical
- // distortion is cancelled
-
- scale = (int)(cos_table[temp_ray]/(dist_x))>>1;
-
- vz_buffer[ray] = dist_x;
-
- sliver_buffer[ray].sliv_hit_type = 0+(2*b_toggle);
-
- // clip wall sliver against view port
-
- if (scale>(MAX_SCALE-1)) scale=(MAX_SCALE-1);
-
- sliver_buffer[ray].scale_r = scale-1;
-
- if (scale>(WINDOW_HALF_HEIGHT))
- {
- scale=(WINDOW_HALF_HEIGHT);
- }
-
- sliver_buffer[ray].sliv_scale = scale-1;
-
- // set up parameters for assembly language
-
- sliver_buffer[ray].sliv_texture = wall_frames.frames[x_hit_type-1];
-
- if (x_hit_type != 3)
- sliver_buffer[ray].sliv_column = (yi_save & 0x003f);
- else
- sliver_buffer[ray].sliv_column = dor_x_inc;
-
- sliver_buffer[ray].sliv_top = WINDOW_MIDDLE - (scale >> 1);
- sliver_buffer[ray].sliv_ray = COLUMN_OFFSET-ray;
-
- } // end if
- else // must of hit a horizontal wall first
- {
-
- // there was a vertical wall closer than the horizontal
-
- // compute actual scale and multiply by view filter so that spherical
- // distortion is cancelled
-
- scale = (int)(cos_table[temp_ray]/(dist_y))>>1;
-
- vz_buffer[ray] = dist_y;
-
- sliver_buffer[ray].sliv_hit_type = 1+(2*a_toggle);
-
- // do clipping again
-
- if (scale>(MAX_SCALE-1)) scale=(MAX_SCALE-1);
-
- sliver_buffer[ray].scale_r = scale-1;
-
- if (scale>(WINDOW_HALF_HEIGHT))
- {
- scale=(WINDOW_HALF_HEIGHT);
- }
-
- sliver_buffer[ray].sliv_scale = scale-1;
-
- // set up parameters for assembly language
-
- sliver_buffer[ray].sliv_texture = wall_frames.frames[y_hit_type];
-
-
- if (y_hit_type != 3)
- sliver_buffer[ray].sliv_column = (xi_save & 0x003f);
- else
- sliver_buffer[ray].sliv_column = dor_y_inc;
-
- sliver_buffer[ray].sliv_top = WINDOW_MIDDLE - (scale >> 1);
- sliver_buffer[ray].sliv_ray = COLUMN_OFFSET-ray;
-
- } // end else
-
- // S E C T I O N 7 /////////////////////////////////////////////////////////
-
- // cast next ray
-
- // test if view angle need to wrap around
-
- if ((++curr_ang)>=ANGLE_360)
- {
- curr_ang-=ANGLE_360;
- //curr_ang=0;
-
- } // end if
-
- } // end for ray
-
- } // end Ray_Caster
-
- void Weak_Attempt(void)
- {
- // This is a weak attempt at applying some linear interpolation in the ray casting
- // It does speed up things a little bit... but it definitely has it's flaws...
-
- // essential... since the ray caster casts rays FOR EVERY OTHER COLUMN of the screen...
- // ...this procedure fills in the blanks... (i.e. puts data into the sliver_buffer at
- // IN BETWEEN points in the array)
-
- int index,temp1,temp2;
-
-
- for (index = 1 ; index < (VIEW_CONE); index+=2)
- {
- sliver_buffer[index].sliv_ray=COLUMN_OFFSET-index;
-
- if ((index)==(VIEW_CONE-1)) //index-1
- {
- sliver_buffer[index].sliv_hit_type=sliver_buffer[index-1].sliv_hit_type;
- sliver_buffer[index].sliv_column=sliver_buffer[index-1].sliv_column;
- sliver_buffer[index].sliv_top=sliver_buffer[index-1].sliv_column;
- vz_buffer[index] = vz_buffer[index-1];
- sliver_buffer[index].sliv_scale=sliver_buffer[index-1].sliv_scale;
- sliver_buffer[index].scale_r=sliver_buffer[index-1].scale_r;
- sliver_buffer[index].sliv_texture=sliver_buffer[index-1].sliv_texture;
- }
- else
- if (sliver_buffer[index-1].sliv_hit_type!=sliver_buffer[index+1].sliv_hit_type)
- {
- sliver_buffer[index].sliv_hit_type=sliver_buffer[index+1].sliv_hit_type;
- sliver_buffer[index].sliv_column = sliver_buffer[index+1].sliv_column;
- sliver_buffer[index].sliv_top = sliver_buffer[index+1].sliv_top;
-
- vz_buffer[index] = vz_buffer[index+1];
-
- // clip wall sliver against view port
-
- sliver_buffer[index].sliv_scale = sliver_buffer[index+1].sliv_scale;
-
- sliver_buffer[index].scale_r = sliver_buffer[index+1].scale_r;
-
- sliver_buffer[index].sliv_texture = sliver_buffer[index+1].sliv_texture;
- }
- else
- if ((sliver_buffer[index-1].sliv_hit_type==sliver_buffer[index+1].sliv_hit_type) &&
- (((vz_buffer[index-1] - vz_buffer[index+1]) > 64) ||
- ((vz_buffer[index-1] - vz_buffer[index+1]) < -64)))
- {
- sliver_buffer[index].sliv_hit_type=sliver_buffer[index+1].sliv_hit_type;
- sliver_buffer[index].sliv_column = sliver_buffer[index+1].sliv_column;
- sliver_buffer[index].sliv_top = sliver_buffer[index+1].sliv_top;
-
- vz_buffer[index] = vz_buffer[index+1];
-
- sliver_buffer[index].sliv_scale = sliver_buffer[index+1].sliv_scale;
-
- sliver_buffer[index].scale_r = sliver_buffer[index+1].scale_r;
-
- sliver_buffer[index].sliv_texture = sliver_buffer[index+1].sliv_texture;
- }
- else
- {
- sliver_buffer[index].sliv_hit_type=sliver_buffer[index+1].sliv_hit_type;
- vz_buffer[index] = (vz_buffer[index-1]+vz_buffer[index+1])>>1;
-
- sliver_buffer[index].sliv_scale = (sliver_buffer[index-1].sliv_scale+sliver_buffer[index+1].sliv_scale)>>1;
-
- sliver_buffer[index].scale_r = (sliver_buffer[index-1].scale_r+sliver_buffer[index+1].scale_r)>>1;
-
- sliver_buffer[index].sliv_texture = sliver_buffer[index-1].sliv_texture;
-
- temp2 = sliver_buffer[index+1].sliv_column;
- temp1 = sliver_buffer[index-1].sliv_column;
-
- if (sliver_buffer[index-1].sliv_hit_type==0)
- {
- if (sliver_buffer[index-1].sliv_column < sliver_buffer[index+1].sliv_column)
- temp1 = sliver_buffer[index-1].sliv_column + 64;
-
- }
- else
- if (sliver_buffer[index-1].sliv_hit_type==1)
- {
- if (sliver_buffer[index-1].sliv_column > sliver_buffer[index+1].sliv_column)
- temp2 = sliver_buffer[index+1].sliv_column + 64;
-
- }
- else
- if (sliver_buffer[index-1].sliv_hit_type==2)
- {
- if (sliver_buffer[index-1].sliv_column > sliver_buffer[index+1].sliv_column)
- temp2 = sliver_buffer[index+1].sliv_column + 64;
-
- }
- else
- if (sliver_buffer[index-1].sliv_hit_type==3)
- {
- if (sliver_buffer[index-1].sliv_column < sliver_buffer[index+1].sliv_column)
- temp1 = sliver_buffer[index-1].sliv_column + 64;
-
- }
-
-
- sliver_buffer[index].sliv_column = ((temp1+temp2)>>1)&0x003f;
-
-
- sliver_buffer[index].sliv_top = WINDOW_MIDDLE - (sliver_buffer[index].sliv_scale-1);
- }
- }
- } // end Weak_Attempt
-
- /////////////////////////////////////////////////////////////////////////////
-
- void Draw_Walls(void)
- {
- // This function draws each plane of the final screen image separately
-
- int ray;
- unsigned short temp_column_offset;
-
- _asm
- {
- mov dx,SEQUENCER // address the sequencer
- mov al,SEQ_PLANE_ENABLE // select the plane enable register
- mov ah,08h // select plane 3
- out dx,ax // do it baby!
- } // end asm
-
- for (ray = 0; ray < VIEW_CONE; ray+=4)
- {
- scale_row = scale_table[sliver_buffer[ray].scale_r];
-
- sliver_scale = sliver_buffer[ray].sliv_scale;
-
- // set up parameters for assembly language
-
- sliver_texture = sliver_buffer[ray].sliv_texture;
- sliver_column = sliver_buffer[ray].sliv_column;
- sliver_top = sliver_buffer[ray].sliv_top;
- sliver_ray = sliver_buffer[ray].sliv_ray;
-
- // render the sliver
-
- Render_Sliver();
- }
-
- _asm
- {
- mov dx,SEQUENCER // address the sequencer
- mov al,SEQ_PLANE_ENABLE // select the plane enable register
- mov ah,04h // select plane 2
- out dx,ax // do it baby!
- } // end asm
-
- for (ray = 1; ray < VIEW_CONE; ray+=4)
- {
- scale_row = scale_table[sliver_buffer[ray].scale_r];
-
-
- sliver_scale = sliver_buffer[ray].sliv_scale;
-
- // set up parameters for assembly language
-
- sliver_texture = sliver_buffer[ray].sliv_texture;
- sliver_column = sliver_buffer[ray].sliv_column;
- sliver_top = sliver_buffer[ray].sliv_top;
- sliver_ray = sliver_buffer[ray].sliv_ray;
-
- // render the sliver
-
- Render_Sliver();
- }
-
- _asm
- {
- mov dx,SEQUENCER // address the sequencer
- mov al,SEQ_PLANE_ENABLE // select the plane enable register
- mov ah,02h // select plane 1
- out dx,ax // do it baby!
- } // end asm
-
- for (ray = 2; ray < VIEW_CONE; ray+=4)
- {
- scale_row = scale_table[sliver_buffer[ray].scale_r];
-
- sliver_scale = sliver_buffer[ray].sliv_scale;
-
- // set up parameters for assembly language
-
- sliver_texture = sliver_buffer[ray].sliv_texture;
- sliver_column = sliver_buffer[ray].sliv_column;
- sliver_top = sliver_buffer[ray].sliv_top;
- sliver_ray = sliver_buffer[ray].sliv_ray;
-
- // render the sliver
-
- Render_Sliver();
- }
-
- _asm
- {
- mov dx,SEQUENCER // address the sequencer
- mov al,SEQ_PLANE_ENABLE // select the plane enable register
- mov ah,01h // select plane 0
- out dx,ax // do it baby!
- } // end asm
-
- for (ray = 3; ray < VIEW_CONE; ray+=4)
- {
- scale_row = scale_table[sliver_buffer[ray].scale_r];
-
- sliver_scale = sliver_buffer[ray].sliv_scale;
-
- // set up parameters for assembly language
-
- sliver_texture = sliver_buffer[ray].sliv_texture;
- sliver_column = sliver_buffer[ray].sliv_column;
- sliver_top = sliver_buffer[ray].sliv_top;
- sliver_ray = sliver_buffer[ray].sliv_ray;
-
- // render the sliver
-
- Render_Sliver();
- }
-
- } // end Draw_Walls
-
- int Enemy_Line_Of_Sight(long en_x, long en_y, long en_ang, long en_dist)
- {
- // This function is like a completely stripped Ray Caster...
- // it casts rays out along only one vector...
-
- // ... to "see" if a wall sliver is in between the player and the enemy!
-
- register int
- curr_ang,
- cell_x, // the current cell that the ray is in
- cell_y,
- ray, // the current ray being cast 0-320
- x_hit_type, // records the block that was intersected, used to figure
- y_hit_type, // out which texture to use
- x_bound, // the next vertical and horizontal intersection point
- y_bound,
- next_y_cell, // used to figure out the quadrant of the ray
- next_x_cell,
- xray=0, // tracks the progress of a ray looking for Y interesctions
- yray=0, // tracks the progress of a ray looking for X interesctions
-
- x_delta, // the amount needed to move to get to the next cell
- y_delta, // position
- xb_save,
- yb_save,
- xi_save, // used to save exact x and y intersection points
- yi_save;
-
- int x_anded,y_anded;
-
- register long
- dist_x, // the distance of the x and y ray intersections from
- dist_y; // the viewpoint
-
- register float xi, // used to track the x and y intersections
- yi;
-
- int temp_ray;
-
- curr_ang = en_ang;
-
- x_anded = (int)(en_x & 0xffc0);
- y_anded = (int)(en_y & 0xffc0);
-
-
- // S E C T I O N 2 /////////////////////////////////////////////////////////
-
-
- // compute first x intersection
-
- // need to know which half plane we are casting from relative to Y axis
-
- if (curr_ang >= ANGLE_0 && curr_ang < ANGLE_180)
- {
-
- // compute first horizontal line that could be intersected with ray
- // note: it will be above player
-
- y_bound = (CELL_Y_SIZE + y_anded);
-
- // compute delta to get to next horizontal line
-
- y_delta = CELL_Y_SIZE;
-
- // based on first possible horizontal intersection line, compute X
- // intercept, so that casting can begin
-
- xi = inv_tan_table[curr_ang] * (y_bound - en_y) + en_x;
-
- // set cell delta
-
- next_y_cell = 0;
-
- } // end if upper half plane
- else
- {
- // compute first horizontal line that could be intersected with ray
- // note: it will be below player
-
- y_bound = y_anded;
-
- // compute delta to get to next horizontal line
-
- y_delta = -CELL_Y_SIZE;
-
- // based on first possible horizontal intersection line, compute X
- // intercept, so that casting can begin
-
- xi = inv_tan_table[curr_ang] * (y_bound - en_y) + en_x;
-
- // set cell delta
-
- next_y_cell = -1;
-
- } // end else lower half plane
-
- // S E C T I O N 3 /////////////////////////////////////////////////////////
-
- // compute first y intersection
-
- // need to know which half plane we are casting from relative to X axis
-
- if (curr_ang < ANGLE_90 || curr_ang >= ANGLE_270)
- {
-
- // compute first vertical line that could be intersected with ray
- // note: it will be to the right of player
-
- x_bound = (int)(CELL_X_SIZE + x_anded);
-
- // compute delta to get to next vertical line
-
- x_delta = CELL_X_SIZE;
-
- // based on first possible vertical intersection line, compute Y
- // intercept, so that casting can begin
-
- yi = tan_table[curr_ang] * (x_bound - en_x) + en_y;
-
- // set cell delta
-
- next_x_cell = 0;
-
- } // end if right half plane
- else
- {
-
- // compute first vertical line that could be intersected with ray
- // note: it will be to the left of player
-
- x_bound = x_anded;
-
- // compute delta to get to next vertical line
-
- x_delta = -CELL_X_SIZE;
-
- // based on first possible vertical intersection line, compute Y
- // intercept, so that casting can begin
-
- yi = tan_table[curr_ang] * (x_bound - en_x) + en_y;
-
- // set cell delta
-
- next_x_cell = -1;
-
- } // end else right half plane
-
-
- // begin cast
-
- // casting = 2; // two rays to cast simultaneously
- xray=yray = 0; // reset intersection flags
-
- cell_x = ( (x_bound+next_x_cell) >> CELL_X_SIZE_FP);
-
- cell_y = (int)yi;
- cell_y>>=CELL_Y_SIZE_FP;
-
- // test if there is a block where the current x ray is intersecting
-
- if (world[cell_y][cell_x].block_type!=0)
- {
- xray = INTERSECTION_FOUND;
- }
- // S E C T I O N 4 /////////////////////////////////////////////////////////
-
- while(xray!=INTERSECTION_FOUND)
- {
-
- // continue casting each ray in parallel
-
- yi += y_step[curr_ang];
-
- // find next possible x intercept point
-
- x_bound += x_delta;
-
- // compute current map position to inspect
-
- cell_x = ( (x_bound+next_x_cell) >> CELL_X_SIZE_FP);
-
- cell_y = (int)yi;
- cell_y>>=CELL_Y_SIZE_FP;
-
- // test if there is a block where the current x ray is intersecting
-
- if (world[cell_y][cell_x].block_type!=0)
- {
- xray = INTERSECTION_FOUND;
- } // end if a hit
-
- } // end if x ray has intersected
-
- dist_x = (long)((yi - en_y) * inv_sin_table[curr_ang]);
- yi_save = (int)yi;
- xb_save = x_bound;
-
- // S E C T I O N 5 /////////////////////////////////////////////////////////
-
- cell_x = xi;
- cell_x>>=CELL_X_SIZE_FP;
-
- cell_y = ( (y_bound + next_y_cell) >> CELL_Y_SIZE_FP);
-
- // test if there is a block where the current y ray is intersecting
-
- if (world[cell_y][cell_x].block_type!=0)
- {
- yray = INTERSECTION_FOUND;
- }
-
- while (yray!=INTERSECTION_FOUND)
- {
-
- xi += x_step[curr_ang];
-
- // compute next possible y intercept
-
- y_bound += y_delta;
- // compute current map position to inspect
-
- cell_x = xi;
- cell_x>>=CELL_X_SIZE_FP;
-
- cell_y = ( (y_bound + next_y_cell) >> CELL_Y_SIZE_FP);
-
- // test if there is a block where the current y ray is intersecting
-
- if (world[cell_y][cell_x].block_type!=0)
- {
- yray = INTERSECTION_FOUND;
- } // end if a hit
-
- } // end while not done
-
- dist_y = (long)((xi - en_x) * inv_cos_table[curr_ang]);
- xi_save = (int)xi;
- yb_save = y_bound;
-
- // S E C T I O N 6 /////////////////////////////////////////////////////////
-
- // at this point, we know that the ray has succesfully hit both a
- // vertical wall and a horizontal wall, so we need to see which one
- // was closer and then render it
-
- if ((dist_x < en_dist) || (dist_y < en_dist))
- return(0);
- else
- return(1);
-
- } // end Enemy_Line_Of_Sight
-
-
- void Translate_Player(long dx, long dy)
- {
- long x_cell,y_cell,x_sub_cell,y_sub_cell;
-
- // test if user has bumped into a wall i.e. test if there
- // is a cell within the direction of motion, if so back up !
-
- // compute cell position
-
- x_cell = x/CELL_X_SIZE;
- y_cell = y/CELL_Y_SIZE;
-
- // compute position relative to cell
-
- x_sub_cell = x % CELL_X_SIZE;
- y_sub_cell = y % CELL_Y_SIZE;
-
-
- // test if player is bumping into a wall
- // resolve motion into it's x and y components
-
- if (dx>0 )
- {
- // moving right
-
- if ((Block_Map[y_cell][x_cell+1] != 0) &&
- (x_sub_cell > (OVERBOARD ) ) )
- {
- // back player up amount he steped over the line
-
- x = ((x_cell)<<CELL_X_SIZE_FP) + OVERBOARD;
-
- } // end if need to back up
- else
- if ((Block_Map[y_cell+1][x_cell+1] != 0) &&
- (x_sub_cell > (OVERBOARD ) ) &&
- (y_sub_cell > (OVERBOARD ) ) &&
- (Block_Map[y_cell+1][x_cell] == 0) )
- {
- x = ((x_cell)<<CELL_X_SIZE_FP) + OVERBOARD;
- }
- else
- if ((Block_Map[y_cell-1][x_cell+1] != 0) &&
- (x_sub_cell > (OVERBOARD ) ) &&
- (y_sub_cell < (CELL_Y_SIZE-OVERBOARD ) ) &&
- (Block_Map[y_cell-1][x_cell] == 0) )
- {
- x = ((x_cell)<<CELL_X_SIZE_FP) + OVERBOARD;
- }
-
- }
- else
- {
- // moving left
-
- if ((Block_Map[y_cell][x_cell-1] != 0) &&
- (x_sub_cell < (CELL_X_SIZE-OVERBOARD) ) )
- {
- // back player up amount he steped over the line
-
- x = ((x_cell)<<CELL_X_SIZE_FP) + (CELL_X_SIZE-OVERBOARD);
-
- } // end if need to back up
- else
- if ((Block_Map[y_cell+1][x_cell-1] != 0) &&
- (x_sub_cell < (CELL_X_SIZE-OVERBOARD) ) &&
- (y_sub_cell > (OVERBOARD ) ) &&
- (Block_Map[y_cell+1][x_cell] == 0) )
- {
- x = ((x_cell)<<CELL_X_SIZE_FP) + (CELL_X_SIZE-OVERBOARD);
- }
- else
- if ((Block_Map[y_cell-1][x_cell-1] != 0) &&
- (x_sub_cell < (CELL_X_SIZE-OVERBOARD) ) &&
- (y_sub_cell < (CELL_Y_SIZE-OVERBOARD ) ) &&
- (Block_Map[y_cell-1][x_cell] == 0) )
- {
- x = ((x_cell)<<CELL_X_SIZE_FP) + (CELL_X_SIZE-OVERBOARD);
- }
-
-
- } // end else
-
- // compute cell position
-
- x_cell = x/CELL_X_SIZE;
- y_cell = y/CELL_Y_SIZE;
-
- // compute position relative to cell
-
- x_sub_cell = x % CELL_X_SIZE;
- y_sub_cell = y % CELL_Y_SIZE;
-
- if (dy>0 )
- {
- // moving up
-
- if ((Block_Map[(y_cell+1)][x_cell] != 0) &&
- (y_sub_cell > ( OVERBOARD ) ) )
- {
- // back player up amount he steped over the line
-
- y = ((y_cell)<<CELL_Y_SIZE_FP) + OVERBOARD;
-
- } // end if need to back up
- else
- if ((Block_Map[(y_cell+1)][x_cell+1] != 0) &&
- (y_sub_cell > ( OVERBOARD ) ) &&
- (x_sub_cell > (OVERBOARD) ) &&
- (Block_Map[y_cell][x_cell+1] == 0) )
- {
- // back player up amount he steped over the line
-
- y = ((y_cell)<<CELL_Y_SIZE_FP) + OVERBOARD;
-
- } // end if need to back up
- else
- if ((Block_Map[(y_cell+1)][x_cell-1] != 0) &&
- (y_sub_cell > (OVERBOARD ) ) &&
- (x_sub_cell < (CELL_X_SIZE-OVERBOARD ) ) &&
- (Block_Map[y_cell][x_cell-1] == 0) )
- {
- // back player up amount he steped over the line
-
- y = ((y_cell)<<CELL_Y_SIZE_FP) + OVERBOARD;
-
- } // end if need to back up
-
- }
- else
- {
- // moving down
-
- if ((Block_Map[(y_cell-1)][x_cell] != 0) &&
- (y_sub_cell < (CELL_X_SIZE-OVERBOARD) ) )
- {
- // back player up amount he steped over the line
-
- y = ((y_cell)<<CELL_Y_SIZE_FP) + (CELL_Y_SIZE-OVERBOARD);
-
- } // end if need to back up
- else
- if ((Block_Map[(y_cell-1)][x_cell+1] != 0) &&
- (y_sub_cell < (CELL_Y_SIZE-OVERBOARD ) ) &&
- (x_sub_cell > (OVERBOARD) ) &&
- (Block_Map[y_cell][x_cell+1] == 0) )
- {
- // back player up amount he steped over the line
-
- y = ((y_cell)<<CELL_Y_SIZE_FP) + (CELL_Y_SIZE-OVERBOARD);
-
- } // end if need to back up
- else
- if ((Block_Map[(y_cell-1)][x_cell-1] != 0) &&
- (y_sub_cell < (CELL_Y_SIZE-OVERBOARD ) ) &&
- (x_sub_cell < (CELL_X_SIZE-OVERBOARD ) ) &&
- (Block_Map[y_cell][x_cell-1] == 0) )
- {
- // back player up amount he steped over the line
-
- y = ((y_cell)<<CELL_Y_SIZE_FP) + (CELL_Y_SIZE-OVERBOARD);
-
- } // end if need to back up
-
- } // end else
- }
-
- void Translate_Enemy(int enem_num, long dx, long dy)
- {
- long x_cell,y_cell,x_sub_cell,y_sub_cell;
-
- // test if user has bumped into a wall i.e. test if there
- // is a cell within the direction of motion, if so back up !
-
- // compute cell position
-
- x_cell = enemies[enem_num].vitals.x/CELL_X_SIZE;
- y_cell = enemies[enem_num].vitals.y/CELL_Y_SIZE;
-
- // compute position relative to cell
-
- x_sub_cell = enemies[enem_num].vitals.x % CELL_X_SIZE;
- y_sub_cell = enemies[enem_num].vitals.y % CELL_Y_SIZE;
-
-
- // test if player is bumping into a wall
- // resolve motion into it's x and y components
-
- if (dx>0 )
- {
- // moving right
-
- if ((Block_Map[y_cell][x_cell+1] != 0) &&
- (x_sub_cell > (OVERBOARD_FOR_ENEMIES ) ) )
- {
- // back player up amount he steped over the line
-
- enemies[enem_num].vitals.x = ((x_cell)<<CELL_X_SIZE_FP) + OVERBOARD_FOR_ENEMIES;
-
- if (((world[y_cell][x_cell+1].block_type == 2) || (world[y_cell][x_cell+1].block_type == 3)) &&
- ((doors[world[y_cell][x_cell+1].door_id].door_state == CLOSED) ||
- (doors[world[y_cell][x_cell+1].door_id].door_state == CLOSING)))
- {
-
- // make door disappear by starting process
-
- doors[world[y_cell][x_cell+1].door_id].door_state = OPENING;
- doors[world[y_cell][x_cell+1].door_id].door_increment += 6;
-
- }
- } // end if need to back up
- else
- if ((Block_Map[y_cell+1][x_cell+1] != 0) &&
- (x_sub_cell > (OVERBOARD_FOR_ENEMIES ) ) &&
- (y_sub_cell > (OVERBOARD_FOR_ENEMIES ) ) &&
- (Block_Map[y_cell+1][x_cell] == 0) )
- {
- enemies[enem_num].vitals.x = ((x_cell)<<CELL_X_SIZE_FP) + OVERBOARD_FOR_ENEMIES;
- }
- else
- if ((Block_Map[y_cell-1][x_cell+1] != 0) &&
- (x_sub_cell > (OVERBOARD_FOR_ENEMIES ) ) &&
- (y_sub_cell < (CELL_Y_SIZE-OVERBOARD_FOR_ENEMIES ) ) &&
- (Block_Map[y_cell-1][x_cell] == 0) )
- {
- enemies[enem_num].vitals.x = ((x_cell)<<CELL_X_SIZE_FP) + OVERBOARD_FOR_ENEMIES;
- }
-
- }
- else
- {
- // moving left
-
- if ((Block_Map[y_cell][x_cell-1] != 0) &&
- (x_sub_cell < (CELL_X_SIZE-OVERBOARD_FOR_ENEMIES) ) )
- {
- // back player up amount he steped over the line
-
- enemies[enem_num].vitals.x = ((x_cell)<<CELL_X_SIZE_FP) + (CELL_X_SIZE-OVERBOARD_FOR_ENEMIES);
-
- if (((world[y_cell][x_cell-1].block_type == 2) || (world[y_cell][x_cell-1].block_type == 3)) &&
- ((doors[world[y_cell][x_cell-1].door_id].door_state == CLOSED) ||
- (doors[world[y_cell][x_cell-1].door_id].door_state == CLOSING)))
- {
-
- // make door disappear by starting process
-
- doors[world[y_cell][x_cell-1].door_id].door_state = OPENING;
- doors[world[y_cell][x_cell-1].door_id].door_increment += 6;
-
- }
- } // end if need to back up
- else
- if ((Block_Map[y_cell+1][x_cell-1] != 0) &&
- (x_sub_cell < (CELL_X_SIZE-OVERBOARD_FOR_ENEMIES) ) &&
- (y_sub_cell > (OVERBOARD_FOR_ENEMIES ) ) &&
- (Block_Map[y_cell+1][x_cell] == 0) )
- {
- enemies[enem_num].vitals.x = ((x_cell)<<CELL_X_SIZE_FP) + (CELL_X_SIZE-OVERBOARD_FOR_ENEMIES);
- }
- else
- if ((Block_Map[y_cell-1][x_cell-1] != 0) &&
- (x_sub_cell < (CELL_X_SIZE-OVERBOARD_FOR_ENEMIES) ) &&
- (y_sub_cell < (CELL_Y_SIZE-OVERBOARD_FOR_ENEMIES ) ) &&
- (Block_Map[y_cell-1][x_cell] == 0) )
- {
- enemies[enem_num].vitals.x = ((x_cell)<<CELL_X_SIZE_FP) + (CELL_X_SIZE-OVERBOARD_FOR_ENEMIES);
- }
-
-
- } // end else
-
- // compute cell position
-
- x_cell = enemies[enem_num].vitals.x/CELL_X_SIZE;
- y_cell = enemies[enem_num].vitals.y/CELL_Y_SIZE;
-
- // compute position relative to cell
-
- x_sub_cell = enemies[enem_num].vitals.x % CELL_X_SIZE;
- y_sub_cell = enemies[enem_num].vitals.y % CELL_Y_SIZE;
-
- if (dy>0 )
- {
- // moving up
-
- if ((Block_Map[(y_cell+1)][x_cell] != 0) &&
- (y_sub_cell > ( OVERBOARD_FOR_ENEMIES ) ) )
- {
- // back player up amount he steped over the line
-
- enemies[enem_num].vitals.y = ((y_cell)<<CELL_Y_SIZE_FP) + OVERBOARD_FOR_ENEMIES;
-
- if (((world[y_cell+1][x_cell].block_type == 2) || (world[y_cell+1][x_cell].block_type == 3)) &&
- ((doors[world[y_cell+1][x_cell].door_id].door_state == CLOSED) ||
- (doors[world[y_cell+1][x_cell].door_id].door_state == CLOSING)))
- {
-
- // make door disappear by starting process
-
- doors[world[y_cell+1][x_cell].door_id].door_state = OPENING;
- doors[world[y_cell+1][x_cell].door_id].door_increment += 6;
-
- }
- } // end if need to back up
- else
- if ((Block_Map[(y_cell+1)][x_cell+1] != 0) &&
- (y_sub_cell > ( OVERBOARD_FOR_ENEMIES ) ) &&
- (x_sub_cell > (OVERBOARD_FOR_ENEMIES) ) &&
- (Block_Map[y_cell][x_cell+1] == 0) )
- {
- // back player up amount he steped over the line
-
- enemies[enem_num].vitals.y = ((y_cell)<<CELL_Y_SIZE_FP) + OVERBOARD_FOR_ENEMIES;
-
- } // end if need to back up
- else
- if ((Block_Map[(y_cell+1)][x_cell-1] != 0) &&
- (y_sub_cell > (OVERBOARD_FOR_ENEMIES ) ) &&
- (x_sub_cell < (CELL_X_SIZE-OVERBOARD_FOR_ENEMIES ) ) &&
- (Block_Map[y_cell][x_cell-1] == 0) )
- {
- // back player up amount he steped over the line
-
- enemies[enem_num].vitals.y = ((y_cell)<<CELL_Y_SIZE_FP) + OVERBOARD_FOR_ENEMIES;
-
- } // end if need to back up
-
- }
- else
- {
- // moving down
-
- if ((Block_Map[(y_cell-1)][x_cell] != 0) &&
- (y_sub_cell < (CELL_X_SIZE-OVERBOARD_FOR_ENEMIES) ) )
- {
- // back player up amount he steped over the line
-
- enemies[enem_num].vitals.y = ((y_cell)<<CELL_Y_SIZE_FP) + (CELL_Y_SIZE-OVERBOARD_FOR_ENEMIES);
-
- if (((world[y_cell-1][x_cell].block_type == 2) || (world[y_cell-1][x_cell].block_type == 3)) &&
- ((doors[world[y_cell-1][x_cell].door_id].door_state == CLOSED) ||
- (doors[world[y_cell-1][x_cell].door_id].door_state == CLOSING)))
- {
-
- // make door disappear by starting process
-
- doors[world[y_cell-1][x_cell].door_id].door_state = OPENING;
- doors[world[y_cell-1][x_cell].door_id].door_increment += 6;
-
- }
- } // end if need to back up
- else
- if ((Block_Map[(y_cell-1)][x_cell+1] != 0) &&
- (y_sub_cell < (CELL_Y_SIZE-OVERBOARD_FOR_ENEMIES ) ) &&
- (x_sub_cell > (OVERBOARD_FOR_ENEMIES) ) &&
- (Block_Map[y_cell][x_cell+1] == 0) )
- {
- // back player up amount he steped over the line
-
- enemies[enem_num].vitals.y = ((y_cell)<<CELL_Y_SIZE_FP) + (CELL_Y_SIZE-OVERBOARD_FOR_ENEMIES);
-
- } // end if need to back up
- else
- if ((Block_Map[(y_cell-1)][x_cell-1] != 0) &&
- (y_sub_cell < (CELL_Y_SIZE-OVERBOARD_FOR_ENEMIES ) ) &&
- (x_sub_cell < (CELL_X_SIZE-OVERBOARD_FOR_ENEMIES ) ) &&
- (Block_Map[y_cell][x_cell-1] == 0) )
- {
- // back player up amount he steped over the line
-
- enemies[enem_num].vitals.y = ((y_cell)<<CELL_Y_SIZE_FP) + (CELL_Y_SIZE-OVERBOARD_FOR_ENEMIES);
-
- } // end if need to back up
-
- } // end else
- }
-
-
- void Draw_ReDraw_Frame(void)
- {
- // DRAW LINES FOR TOP OF VIEWPORT
-
- Line_H_Mode_Y(WINDOW_LEFT-4,WINDOW_RIGHT+3,WINDOW_TOP-4,BORDER_COLOR_1);
- Line_H_Mode_Y(WINDOW_LEFT-3,WINDOW_RIGHT+2,WINDOW_TOP-3,BORDER_COLOR_2);
- Line_H_Mode_Y(WINDOW_LEFT-2,WINDOW_RIGHT+1,WINDOW_TOP-2,BORDER_COLOR_3);
- Line_H_Mode_Y(WINDOW_LEFT-1,WINDOW_RIGHT,WINDOW_TOP-1,BORDER_COLOR_4);
-
- // DRAW LINES FOR BOTTOM OF VIEWPORT
-
- Line_H_Mode_Y(WINDOW_LEFT-4,WINDOW_RIGHT+3,WINDOW_BOTTOM+3,BORDER_COLOR_1);
- Line_H_Mode_Y(WINDOW_LEFT-3,WINDOW_RIGHT+2,WINDOW_BOTTOM+2,BORDER_COLOR_2);
- Line_H_Mode_Y(WINDOW_LEFT-2,WINDOW_RIGHT+1,WINDOW_BOTTOM+1,BORDER_COLOR_3);
- Line_H_Mode_Y(WINDOW_LEFT-1,WINDOW_RIGHT,WINDOW_BOTTOM,BORDER_COLOR_4);
-
- // DRAW LINES FOR LEFT OF VIEWPORT
-
- Line_V_Mode_Y(WINDOW_TOP-4,WINDOW_BOTTOM+3,WINDOW_LEFT-4,BORDER_COLOR_1);
- Line_V_Mode_Y(WINDOW_TOP-3,WINDOW_BOTTOM+2,WINDOW_LEFT-3,BORDER_COLOR_2);
- Line_V_Mode_Y(WINDOW_TOP-2,WINDOW_BOTTOM+1,WINDOW_LEFT-2,BORDER_COLOR_3);
- Line_V_Mode_Y(WINDOW_TOP-1,WINDOW_BOTTOM,WINDOW_LEFT-1,BORDER_COLOR_4);
-
- // DRAW LINES FOR RIGHT OF VIEWPORT
-
- Line_V_Mode_Y(WINDOW_TOP-4,WINDOW_BOTTOM+3,WINDOW_RIGHT+3,BORDER_COLOR_1);
- Line_V_Mode_Y(WINDOW_TOP-3,WINDOW_BOTTOM+2,WINDOW_RIGHT+2,BORDER_COLOR_2);
- Line_V_Mode_Y(WINDOW_TOP-2,WINDOW_BOTTOM+1,WINDOW_RIGHT+1,BORDER_COLOR_3);
- Line_V_Mode_Y(WINDOW_TOP-1,WINDOW_BOTTOM,WINDOW_RIGHT,BORDER_COLOR_4);
- } // end Draw_ReDraw_Frame
-
- int Parse_Commands(int argc, char **argv)
- {
- // this function is used to parse the commands line parameters that are to be
- // used as switched to enable different modes of operation
-
- int index; // looping variable
- int a_flag = 1;
-
- for (index=1; index<argc; index++)
- {
- // get the first character from the string
-
- switch(argv[index][0])
- {
-
- case 's': // enable sound effects
- case 'S':
- {
- digital_enabled=1;
- } break;
-
- case 'm': // enable nusic
- case 'M':
- {
- music_enabled=1;
-
- } break;
-
- // more commands would go here...
-
- case 'a': // enable nusic
- case 'A':
- {
- a_flag=0;
-
- } break;
-
- default:break;
-
- } // end switch
-
- } // end for index
-
- return(a_flag);
- } // end Parse_Commands
-
- void Update_Weapon_Statis_Display(int nw_wp_stat)
- {
- unsigned char far *buffer;
-
- int x_index, y_index;
-
- _asm
- {
- mov dx,SEQUENCER // address the sequencer
- mov al,SEQ_PLANE_ENABLE // select the plane enable register
- mov ah,0eh // enable last three planes
- out dx,ax // do it baby!
- } // end inline asm
-
-
- for (x_index = 0; x_index < 56; x_index+=4)
- {
- for (y_index = 0; y_index<3; y_index++)
- {
- buffer = pagey_0_buffer + ((169+y_index)<<6) +
- ((169+y_index)<<4) + ((216+x_index)>>2);
-
- if ((x_index>>2) < nw_wp_stat)
- *buffer = Ammo_Color;
- else
- *buffer = 0;
- }
- }
-
- for (x_index = 0; x_index < 56; x_index+=4)
- {
- for (y_index = 0; y_index<3; y_index++)
- {
- buffer = pagey_1_buffer + ((169+y_index)<<6) +
- ((169+y_index)<<4) + ((216+x_index)>>2);
-
- if ((x_index>>2) < nw_wp_stat)
- *buffer = Ammo_Color;
- else
- *buffer = 0;
- }
- }
-
- } // end Update_Weapon_Statis_Display
-
- void Update_Life_Statis_Display(int nw_life_stat)
- {
- unsigned char far *buffer;
-
- int x_index, y_index;
-
- _asm
- {
- mov dx,SEQUENCER // address the sequencer
- mov al,SEQ_PLANE_ENABLE // select the plane enable register
- mov ah,0eh // enable last three planes
- out dx,ax // do it baby!
- } // end inline asm
-
-
- for (x_index = 0; x_index < 120; x_index+=4)
- {
- for (y_index = 0; y_index<3; y_index++)
- {
- buffer = pagey_0_buffer + ((185+y_index)<<6) +
- ((185+y_index)<<4) + ((184+x_index)>>2);
-
- if ((x_index>>2) < nw_life_stat)
- *buffer = Vitality_Color;
- else
- *buffer = 0;
- }
- }
-
- for (x_index = 0; x_index < 120; x_index+=4)
- {
- for (y_index = 0; y_index<3; y_index++)
- {
- buffer = pagey_1_buffer + ((185+y_index)<<6) +
- ((185+y_index)<<4) + ((184+x_index)>>2);
-
- if ((x_index>>2) < nw_life_stat)
- *buffer = Vitality_Color;
- else
- *buffer = 0;
- }
- }
-
- } // end Update_Life_Statis_Display
-
- void Load_PCX_and_Page_Flip(char *filename, int load_palette_or_not)
- {
- Wait_Retrace_Mode();
-
- Set_Working_Page_Mode_Y(mode_y_page);
-
- PCX_Init((pcx_picture_ptr)&image_pcx);
-
- // load in the textures
-
- PCX_Load((char *)filename, (pcx_picture_ptr)&image_pcx,load_palette_or_not);
-
- PCX_Copy_To_Buffer_XYZ_Mode((pcx_picture_ptr)&image_pcx, video_buffer);
-
- PCX_Delete((pcx_picture_ptr)&image_pcx);
-
- Wait_Display_Mode();
-
- Set_Visual_Page_Mode_Y_Half(mode_y_page);
-
- mode_y_page = !mode_y_page;
- } // end Load_PCX_and_Page_Flip
-
- void Fade_to_Black_and_Paint_Both(int effect)
- {
- if (effect == SCREEN_DARKNESS)
- Screen_Transition(SCREEN_DARKNESS);
- else
- Screen_Transition(FULL_SCREEN_DARKNESS);
-
- Wait_Retrace_Mode();
-
- Set_Working_Page_Mode_Y(mode_y_page);
-
- outp(SEQUENCER,SEQ_PLANE_ENABLE);
- outp(SEQUENCER+1,0x0f);
-
- // clear the screen, remember it is 320x200, but that is divided into four
- // planes, hence we need only to clear 16k out since there will be four planes
- // each being cleared in parallel for a total of 4*16k or 64 = 320x200
- // note: "k" in this example means 1000 not 1024
-
- _asm
- {
-
- les di,video_buffer // point es:di to video buffer, same addre for mode Y
- xor ax,ax // move a zero into al and ah
- mov cx,320*200/8 // number of words to fill(using word is faster than bytes)
- rep stosw // move the color into the video buffer really fast!
-
- } // end inline asm
-
- Wait_Display_Mode();
-
- Set_Visual_Page_Mode_Y_Half(mode_y_page);
-
- mode_y_page = !mode_y_page;
-
- Wait_Retrace_Mode();
-
- Set_Working_Page_Mode_Y(mode_y_page);
-
- outp(SEQUENCER,SEQ_PLANE_ENABLE);
- outp(SEQUENCER+1,0x0f);
-
- // clear the screen, remember it is 320x200, but that is divided into four
- // planes, hence we need only to clear 16k out since there will be four planes
- // each being cleared in parallel for a total of 4*16k or 64 = 320x200
- // note: "k" in this example means 1000 not 1024
-
- _asm
- {
-
- les di,video_buffer // point es:di to video buffer, same addre for mode Y
- xor ax,ax // move a zero into al and ah
- mov cx,320*200/8 // number of words to fill(using word is faster than bytes)
- rep stosw // move the color into the video buffer really fast!
-
- } // end inline asm
-
- } // end Fade_to_Black_and_Paint_Both
-
- void Paint_All_Four_Black(void)
- {
- Wait_Retrace_Mode();
-
- Set_Working_Page_Mode_Y(PAGE_0);
-
- outp(SEQUENCER,SEQ_PLANE_ENABLE);
- outp(SEQUENCER+1,0x0f);
-
- // clear the screen, remember it is 320x200, but that is divided into four
- // planes, hence we need only to clear 16k out since there will be four planes
- // each being cleared in parallel for a total of 4*16k or 64 = 320x200
- // note: "k" in this example means 1000 not 1024
-
- _asm
- {
-
- les di,video_buffer // point es:di to video buffer, same addre for mode Z
- xor ax,ax // move a zero into al and ah
- mov cx,320*200/8 // number of words to fill(using word is faster than bytes)
- rep stosw // move the color into the video buffer really fast!
-
- } // end inline asm
-
- Wait_Retrace_Mode();
-
- Set_Working_Page_Mode_Y(PAGE_1);
-
- outp(SEQUENCER,SEQ_PLANE_ENABLE);
- outp(SEQUENCER+1,0x0f);
-
- // clear the screen, remember it is 320x200, but that is divided into four
- // planes, hence we need only to clear 16k out since there will be four planes
- // each being cleared in parallel for a total of 4*16k or 64 = 320x200
- // note: "k" in this example means 1000 not 1024
-
- _asm
- {
-
- les di,video_buffer // point es:di to video buffer, same addre for mode Z
- xor ax,ax // move a zero into al and ah
- mov cx,320*200/8 // number of words to fill(using word is faster than bytes)
- rep stosw // move the color into the video buffer really fast!
-
- } // end inline asm
-
- Wait_Retrace_Mode();
-
- Set_Working_Page_Mode_Y(PAGE_2);
-
- outp(SEQUENCER,SEQ_PLANE_ENABLE);
- outp(SEQUENCER+1,0x0f);
-
- // clear the screen, remember it is 320x200, but that is divided into four
- // planes, hence we need only to clear 16k out since there will be four planes
- // each being cleared in parallel for a total of 4*16k or 64 = 320x200
- // note: "k" in this example means 1000 not 1024
-
- _asm
- {
-
- les di,video_buffer // point es:di to video buffer, same addre for mode Y
- xor ax,ax // move a zero into al and ah
- mov cx,320*200/8 // number of words to fill(using word is faster than bytes)
- rep stosw // move the color into the video buffer really fast!
-
- } // end inline asm
-
- Wait_Retrace_Mode();
-
- Set_Working_Page_Mode_Y(PAGE_3);
-
- outp(SEQUENCER,SEQ_PLANE_ENABLE);
- outp(SEQUENCER+1,0x0f);
-
- // clear the screen, remember it is 320x200, but that is divided into four
- // planes, hence we need only to clear 16k out since there will be four planes
- // each being cleared in parallel for a total of 4*16k or 64 = 320x200
- // note: "k" in this example means 1000 not 1024
-
- _asm
- {
-
- les di,video_buffer // point es:di to video buffer, same addre for mode Z
- xor ax,ax // move a zero into al and ah
- mov cx,320*200/8 // number of words to fill(using word is faster than bytes)
- rep stosw // move the color into the video buffer really fast!
-
- } // end inline asm
-
- Wait_Retrace_Mode();
-
- Set_Working_Page_Mode_Y(mode_y_page);
-
- } // end Paint_All_Four_Black
-
- void Setup_Initial_Display(void)
- {
- int index;
-
- Wait_Display_Mode();
-
- Set_Visual_Page_Mode_Y_Half(mode_y_page);
-
- mode_y_page = !mode_y_page;
-
- Wait_Retrace_Mode();
-
- Set_Working_Page_Mode_Y(mode_y_page);
-
- Copy_From_Unseen_Vram_to_Page(pagey_0_buffer, video_buffer, 200);
-
- Draw_ReDraw_Frame();
-
- _asm
- {
- mov dx,SEQUENCER // address the sequencer
- mov al,SEQ_PLANE_ENABLE // select the plane enable register
- mov ah,0fh // enable all four planes
- out dx,ax // do it baby!
- } // end inline asm
-
- for (index=WINDOW_TOP; index < WINDOW_MIDDLE; index++)
- {
- fwordset(video_buffer + (index<<6) + (index<<4) + (WINDOW_LEFT>>2),
- 0,((WINDOW_RIGHT-WINDOW_LEFT)>>3));
- }
- for (index=WINDOW_MIDDLE; index < WINDOW_BOTTOM; index++)
- {
- fwordset(video_buffer + (index<<6) + (index<<4) + (WINDOW_LEFT>>2),
- color_1,((WINDOW_RIGHT-WINDOW_LEFT)>>3));
- }
- } // end Setup_Initial_Display
-
- void Erase_Scene(void)
- {
- int index;
-
- _asm
- {
- mov dx,SEQUENCER // address the sequencer
- mov al,SEQ_PLANE_ENABLE // select the plane enable register
- mov ah,0fh // enable all four planes
- out dx,ax // do it baby!
- les di,video_buffer
- } // end inline asm
-
- for (index=WINDOW_TOP; index < WINDOW_MIDDLE; index++)
- {
- fwordset(video_buffer + (index<<6) + (index<<4) + (WINDOW_LEFT>>2),
- 0,((WINDOW_RIGHT-WINDOW_LEFT)>>3));
- }
- for (index=WINDOW_MIDDLE; index < WINDOW_BOTTOM; index++)
- {
- fwordset(video_buffer + (index<<6) + (index<<4) + (WINDOW_LEFT>>2),
- color_1,((WINDOW_RIGHT-WINDOW_LEFT)>>3));
- }
-
- } // end Erase_Scene
-
- long Angle_Between(long play_x, long play_y, long enem_x, long enem_y, int enem_num)
- {
- long x_away, y_away;
- long difference_x, difference_y;
- long total_dist;
- long new_obj_angle;
-
- x_away = x-enem_x;
- y_away = y-enem_y;
-
-
- if ((x_away>1000) || (x_away < -1000)) return(ANGLE_0);
-
- if ((y_away>1000) || (y_away < -1000)) return(ANGLE_0);
-
- if ((y_away == 0) && (x_away == 0))
- return(ANGLE_0);
-
- if (y_away == 0)
- {
- if (x_away < 0)
- return(ANGLE_0);
- else
- if (x_away > 0)
- return(ANGLE_180);
- }
- else
- if (x_away == 0)
- {
- if (y_away < 0)
- return(ANGLE_90);
- else
- if (y_away > 0)
- return(ANGLE_270);
- }
- else
- {
- new_obj_angle = (long)((atan((double)abs(y_away)/(double)abs(x_away)))*(RAD_TO_DEG));
-
- if (x_away > 0)
- {
- if(y_away > 0)
- new_obj_angle = ANGLE_180+new_obj_angle;
- else
- if(y_away < 0)
- new_obj_angle = ANGLE_180-new_obj_angle;
- }
- else
- if (x_away < 0)
- {
- if(y_away > 0)
- new_obj_angle = ANGLE_360-new_obj_angle;
-
- }
- }
-
- return(new_obj_angle);
-
- }
-
- void Find_Object_Distance(void)
- {
- // I packed alot of junk into this routine...
-
- // finding the fixed objects' distances from the player is done at the
- // very beginning of this "function"...
-
- // then... if the user gets REAL CLOSE to an object that can be
- // picked up (ammo, food, or gun upgrade) some other work has to be done...
-
- // I suppose using a linked-list for objects would have been easier,
- // but I've been out of school for a while, and even though I used to
- // be a wiz at linked list related things - I need a memory refresher - badly!
-
- // if an object is picked up, the entire array of object structures is rotated
- // up one notch, from the item picked up, to the end of the object list
- // - including enemies.
-
- long diff_x, diff_y;
- int index;
- int data_move_indice;
- int skip_it;
-
- for (index = 0; index < (Number_Of_Fixed_Objects); index++)
- {
-
- skip_it = 0;
-
- diff_x = x - object_list[index].x;
- diff_y = y - object_list[index].y;
-
- object_list[index].dist = (long)(sqrt((diff_x * diff_x) + (diff_y * diff_y)));
-
- if (object_list[index].dist < 30L)
- {
- if ((object_list[index].kind_of_object == 4) ||
- (object_list[index].kind_of_object == 5) ||
- (object_list[index].kind_of_object == 6))
- {
- what_obj = object_list[index].kind_of_object;
-
- if (object_list[index].kind_of_object == 4)
- {
- if (Player_Ammo == 56)
- skip_it = 1;
-
- Player_Ammo += 8;
-
- if (Player_Ammo>56)
- Player_Ammo = 56;
- }
-
- if (object_list[index].kind_of_object == 5)
- Got_Rapid_Fire = 1;
-
- if (object_list[index].kind_of_object == 6)
- {
- if (Player_Strength == 120)
- skip_it = 1;
-
- Player_Strength += 15;
- if (Player_Strength > 120)
- Player_Strength = 120;
- }
-
- if (!skip_it)
- {
- --Number_Of_Fixed_Objects;
-
- for(data_move_indice = index;
- data_move_indice < (Number_Of_Fixed_Objects);
- data_move_indice++)
- {
- object_list[data_move_indice].kind_of_object = object_list[data_move_indice+1].kind_of_object;
- object_list[data_move_indice].x = object_list[data_move_indice+1].x;
- object_list[data_move_indice].y = object_list[data_move_indice+1].y;
- object_list[data_move_indice].dist = object_list[data_move_indice+1].dist;
- object_list[data_move_indice].angle = object_list[data_move_indice+1].angle;
- object_list[data_move_indice].id_number = object_list[data_move_indice+1].id_number;
-
- initial_object_list[data_move_indice].kind_of_object = initial_object_list[data_move_indice+1].kind_of_object;
- initial_object_list[data_move_indice].x = initial_object_list[data_move_indice+1].x;
- initial_object_list[data_move_indice].y = initial_object_list[data_move_indice+1].y;
- initial_object_list[data_move_indice].dist = initial_object_list[data_move_indice+1].dist;
- initial_object_list[data_move_indice].angle = initial_object_list[data_move_indice+1].angle;
- initial_object_list[data_move_indice].id_number = initial_object_list[data_move_indice+1].id_number;
- }
-
- for (data_move_indice = Number_Of_Fixed_Objects; data_move_indice <= (Number_Of_Fixed_Objects+Number_Of_Enemies); data_move_indice++)
- {
- object_list[data_move_indice].x =
- enemies[data_move_indice-Number_Of_Fixed_Objects].vitals.x;
-
- object_list[data_move_indice].y =
- enemies[data_move_indice-Number_Of_Fixed_Objects].vitals.y;
-
- object_list[data_move_indice].angle =
- enemies[data_move_indice-Number_Of_Fixed_Objects].vitals.angle;
-
- object_list[data_move_indice].kind_of_object =
- enemies[data_move_indice-Number_Of_Fixed_Objects].vitals.kind_of_object;
-
- object_list[data_move_indice].dist =
- enemies[data_move_indice-Number_Of_Fixed_Objects].vitals.dist;
-
- object_list[data_move_indice].id_number =
- enemies[data_move_indice-Number_Of_Fixed_Objects].enem_num;
-
- }
-
- --index;
-
- just_grabbed_something = 1;
-
- } // end if you grabbed an object!
-
- }
- }
- }
-
- for ( ; index<(Number_Of_Fixed_Objects+Number_Of_Enemies); index++)
- {
- diff_x = x - object_list[index].x;
- diff_y = y - object_list[index].y;
-
- object_list[index].dist = (long)(sqrt((diff_x * diff_x) + (diff_y * diff_y)));
-
- }
- }
-
- long Find_Object_Distance_Special(int NUMBER)
- {
- long diff_x, diff_y;
- long Boogie;
-
- diff_x = x - enemies[NUMBER].vitals.x;
- diff_y = y - enemies[NUMBER].vitals.y;
-
- Boogie = (long)(sqrt((diff_x * diff_x) + (diff_y * diff_y)));
-
- return(Boogie);
- }
-
- int Object_Sort_Function(objects *arg1, objects *arg2)
- {
- // this function comapares the average z's of two object and is used by the
- // depth sort surface ordering algorithm
-
- long obj_1;
- long obj_2;
-
- // dereference the poly pointers
-
- obj_1 = arg1->dist;
- obj_2 = arg2->dist;
-
- if (obj_1 > obj_2)
- return(1);
- if (obj_1 < obj_2)
- return(-1);
- else
- return(0);
-
- }
-
- void Sort_Object_List(void)
- {
- qsort( (void *)object_list, (Number_Of_Fixed_Objects+Number_Of_Enemies), sizeof( objects ), Object_Sort_Function );
- }
-
- void Init_Objects(void)
- {
- obj_statistic_list[0].width_factor = .66;
- obj_statistic_list[0].Is_Multi_View = 0;
- obj_statistic_list[0].Is_Half_Height = 0;
- obj_statistic_list[0].Scale_Factor = 21L<<16;
-
- obj_statistic_list[1].width_factor = 1.00;
- obj_statistic_list[1].Is_Multi_View = 0;
- obj_statistic_list[1].Is_Half_Height = 0;
- obj_statistic_list[1].Scale_Factor = 64L<<16;
-
- obj_statistic_list[2].width_factor = .75;
- obj_statistic_list[2].Is_Multi_View = 1;
- obj_statistic_list[2].Is_Half_Height = 1;
- obj_statistic_list[2].Scale_Factor = 32L<<16;
-
- obj_statistic_list[3].width_factor = .75;
- obj_statistic_list[3].Is_Multi_View = 1;
- obj_statistic_list[3].Is_Half_Height = 1;
- obj_statistic_list[3].Scale_Factor = 32L<<16;
-
- obj_statistic_list[4].width_factor = .75;
- obj_statistic_list[4].Is_Multi_View = 0;
- obj_statistic_list[4].Is_Half_Height = 1;
- obj_statistic_list[4].Scale_Factor = 32L<<16;
-
- obj_statistic_list[5].width_factor = .75;
- obj_statistic_list[5].Is_Multi_View = 0;
- obj_statistic_list[5].Is_Half_Height = 1;
- obj_statistic_list[5].Scale_Factor = 32L<<16;
-
- obj_statistic_list[6].width_factor = .75;
- obj_statistic_list[6].Is_Multi_View = 0;
- obj_statistic_list[6].Is_Half_Height = 1;
- obj_statistic_list[6].Scale_Factor = 32L<<16;
-
- object_list = (objects *)malloc(sizeof(objects) * (MAX_OBJECTS+1) );
- initial_object_list = (objects *)malloc(sizeof(objects) * (MAX_OBJECTS+1) );
- enemies = (enemy_objects *)malloc(sizeof(enemy_objects) * (MAX_ENEMIES+1) );
-
- } // end Init_Objects
-
- void Begin_Object_List(void)
- {
- int looper;
-
- for (looper = 0; looper < Number_Of_Fixed_Objects; looper++)
- {
- object_list[looper].x =
- initial_object_list[looper].x;
-
- object_list[looper].y =
- initial_object_list[looper].y;
-
- object_list[looper].angle =
- initial_object_list[looper].angle;
-
- object_list[looper].kind_of_object =
- initial_object_list[looper].kind_of_object;
-
- object_list[looper].dist =
- initial_object_list[looper].dist;
-
- }
-
- for (looper = Number_Of_Fixed_Objects; looper < (Number_Of_Fixed_Objects+Number_Of_Enemies); looper++)
- {
- object_list[looper].x =
- enemies[looper-Number_Of_Fixed_Objects].vitals.x;
-
- object_list[looper].y =
- enemies[looper-Number_Of_Fixed_Objects].vitals.y;
-
- object_list[looper].angle =
- enemies[looper-Number_Of_Fixed_Objects].vitals.angle;
-
- object_list[looper].kind_of_object =
- enemies[looper-Number_Of_Fixed_Objects].vitals.kind_of_object;
-
- object_list[looper].dist =
- enemies[looper-Number_Of_Fixed_Objects].vitals.dist;
-
- object_list[looper].id_number =
- enemies[looper-Number_Of_Fixed_Objects].enem_num;
-
- }
- } // end Begin_Object_List
-
- void Load_64x64_Sprites(sprite_ptr sprite_set, char *filename, int num_cells)
- {
- int index, sprite_row, sprite_column;
- int set = 1;
-
- PCX_Init((pcx_picture_ptr)&image_pcx);
-
- PCX_Load(filename, (pcx_picture_ptr)&image_pcx,1);
-
- Sprite_Init(sprite_set,0,0,64,64,0,0,0,0,0,0);
-
- sprite_row = 0;
- sprite_column = 0;
-
- for (index = 0; index < num_cells; index++)
- {
- if ((index > 0) && ((index % 4) == 0))
- {
- sprite_row+=1;
- sprite_column=0;
- }
- PCX_Get_Sprite((pcx_picture_ptr)&image_pcx, sprite_set,
- index,sprite_column,sprite_row);
-
- sprite_column++;
- }
-
- PCX_Delete((pcx_picture_ptr)&image_pcx);
-
- } // end Load_64x64_Sprites
-
- void Did_Player_Die(void)
- {
- int index;
-
- if (Player_Strength <= 0)
- {
- for (index = 0; index <= 255; index++)
- {
- Read_Color_Reg(index, (RGB_color_ptr)&color_all);
-
- color_all.red += 48;
-
- if (color_all.red > 63)
- color_all.red = 63;
-
- Write_Color_Reg(index, (RGB_color_ptr)&color_all);
-
- }
-
- for(index=0; index<20; index++)
- {
- // loop thru all palette registers
-
- for(pal_reg=0; pal_reg<=255; pal_reg++)
- {
- // get the next color to fade
-
- Read_Color_Reg(pal_reg,(RGB_color_ptr)&color_all);
-
- // test if this color register is already black
- if (color_all.red > 4) color_all.red-=3;
- else
- color_all.red = 0;
-
- if (color_all.green > 4) color_all.green-=3;
- else
- color_all.green = 0;
-
- if (color_all.blue > 4) color_all.blue-=3;
- else
- color_all.blue = 0;
-
- // set the color to a diminshed intensity
-
- Write_Color_Reg(pal_reg,(RGB_color_ptr)&color_all);
-
- } // end for pal reg
-
- // wait a bit
-
- Time_Delay(1);
-
- } // end for index
-
-
-
- if (digital_enabled)
- {
- Sound_Stop();
- Sound_Play((sound_ptr)&global_sounds[4]);
- }
-
- x=(8<<CELL_X_SIZE_FP)+(CELL_X_SIZE>>1);
- y=(8<<CELL_X_SIZE_FP)+(CELL_X_SIZE>>1);
- view_angle=ANGLE_60;
-
- Level_Select(which_map);
-
- New_Lease_On_Life = 1;
-
- Player_Strength = 63;
-
- Player_Ammo = 28;
-
- Got_Rapid_Fire = 0;
-
- }
-
- } // end Did_Player_Die?
-
- void Level_Select(int well)
- {
- if (well == 4)
- {
- Load_World(4);
-
- at_end = 0;
- }
- else
- if (well == 3)
- {
- Load_World(3);
-
- at_end = 0;
- }
- else
- if (well == 2)
- {
- Load_World(2);
- }
- else
- if (well == 1)
- {
- Load_World(1);
- }
- else
- {
- Load_World(0);
- }
- } // end Level_Select
-
- void Process_Flashes(void)
- {
- int index;
-
- if (New_Lease_On_Life)
- {
- for (index = 0; index <= 255; index++)
- {
- Write_Color_Reg(index, (RGB_color_ptr)&old_all[index]);
-
- }
-
- New_Lease_On_Life = 0;
- }
-
- if (just_grabbed_something)
- {
- for (index = 0; index <= 255; index++)
- {
- Write_Color_Reg(index, (RGB_color_ptr)&old_all[index]);
-
- }
-
- just_grabbed_something = 0;
-
- }
- if (Restore_Black)
- {
- color_all.red = 0;
- color_all.blue = 0;
- color_all.green = 0;
-
- Write_Color_Reg(0, (RGB_color_ptr)&color_all);
- Restore_Black = 0;
- }
- } // end Process_Flashes
-
- void Process_Enemy_Events(void)
- {
- int index;
- int enemy_distance;
- int player_weapon_trajectory;
- int AIMED, aimed_sort_of;
- int hitable_arc;
-
- float enemy_dx, enemy_dy;
-
- long tempor;
-
- for (index = 0; index < (Number_Of_Enemies); index++)
- {
- if ((enemies[index].state != DYING) && (enemies[index].state != DEAD))
- {
- tempor = Angle_Between(x, y, enemies[index].vitals.x, enemies[index].vitals.y, index);
-
- if (tempor>=ANGLE_360)
- tempor-=ANGLE_360;
-
- player_weapon_trajectory =
- (tempor+ANGLE_360)-(view_angle+ANGLE_360);
-
- enemy_distance = Find_Object_Distance_Special(index);
-
- if (((int)enemy_distance) < 100)
- hitable_arc = ANGLE_10;
- else
- if (((int)enemy_distance) < 200)
- hitable_arc = ANGLE_8;
- else
- if (((int)enemy_distance) < 300)
- hitable_arc = ANGLE_6;
- else
- if (((int)enemy_distance) < 400)
- hitable_arc = ANGLE_4;
- else
- if (((int)enemy_distance) < 500)
- hitable_arc = ANGLE_2;
-
- if((player_weapon_trajectory < hitable_arc) &&
- (player_weapon_trajectory > -hitable_arc) &&
- (enemy_distance<500L) &&
- (vz_buffer[ANGLE_45+player_weapon_trajectory] > enemy_distance))
- {
- AIMED = 1;
- aimed_sort_of = 1;
- }
- else
- {
- AIMED = 0;
-
- if((player_weapon_trajectory < (ANGLE_10)) &&
- (player_weapon_trajectory > (-ANGLE_10)))
- {
- aimed_sort_of = 1;
- }
- else
- aimed_sort_of = 0;
-
- }
-
- tempor += ANGLE_180;
-
- if (tempor > ANGLE_360)
- tempor-=ANGLE_360;
-
- enemies[(index)].vitals.angle = tempor;
-
- if (enemies[(index)].state == EVADING)
- {
- switch(duck_pattern[enemies[(index)].pat_num])
- {
- case 0: enemies[(index)].vitals.angle+=ANGLE_30; break;
- case 1: enemies[(index)].vitals.angle; break;
- case 2: enemies[(index)].vitals.angle-=ANGLE_30; break;
- }
-
- enemies[(index)].pat_num++;
-
- if (enemies[(index)].pat_num > PAT_LIMIT)
- enemies[(index)].pat_num = 0;
- }
-
- if (enemies[(index)].vitals.angle>ANGLE_360)
- enemies[(index)].vitals.angle-=ANGLE_360;
-
- if (enemies[(index)].vitals.angle<0)
- enemies[(index)].vitals.angle+=ANGLE_360;
-
- if ((player_state == PLAYER_FIRING) &&
- (AIMED) &&
- (the_gun.curr_frame == 4))
- {
- if (Player_Ammo)
- {
- enemies[(index)].state = HIT;
- --enemies[(index)].hit_points;
-
- if (enemies[(index)].hit_points <= 0)
- {
- if (digital_enabled)
- {
- Sound_Stop();
- Sound_Play((sound_ptr)&global_sounds[2]);
- }
-
- enemies[(index)].state = DYING;
- enemies[(index)].threshold = 8;
- enemies[(index)].hit_points = 5;
- }
- }
- }
- else
- if ((player_state == PLAYER_FIRING) &&
- (aimed_sort_of) &&
- (the_gun.curr_frame == 5) &&
- (!Player_Ammo))
- {
- if (enemy_distance < 60)
- {
- enemies[(index)].state = HIT;
- --enemies[(index)].hit_points;
-
- if (enemies[(index)].hit_points <= 0)
- {
- if (digital_enabled)
- {
- Sound_Stop();
- Sound_Play((sound_ptr)&global_sounds[2]);
- }
-
- enemies[(index)].state = DYING;
- enemies[(index)].threshold = 8;
- enemies[(index)].hit_points = 5;
-
- Damage = 250/enemy_distance;
-
- if (Damage > 5) Damage = 5;
- Player_Strength -= Damage;
-
- Red_Factor = 63-(Player_Strength>>1);
- color_all.red = Red_Factor;
- color_all.blue = 0;
- color_all.green = 0;
-
- Write_Color_Reg(0, (RGB_color_ptr)&color_all);
- // Red_Factor++;
-
- // if (Red_Factor == 64)
- // Red_Factor = 16;
-
- Restore_Black = 1;
-
- }
- }
- }
- else
- if (enemy_distance>500L)
- {
- enemies[index].state = WAITING;
- }
- else
- if ((enemy_distance<50L) ||
- (enemies[(index)].state == EVADING))
- {
- if (enemies[(index)].state!=EVADING)
- enemies[(index)].pat_num = (rand()%2)*2;
-
- enemies[(index)].vitals.angle -= ANGLE_180;
-
- if (enemies[(index)].vitals.angle < ANGLE_0)
- enemies[(index)].vitals.angle += ANGLE_360;
-
- tempor = enemies[(index)].vitals.angle;
-
- enemy_dx=cos(6.28*tempor/ANGLE_360)*7;
- enemy_dy=sin(6.28*tempor/ANGLE_360)*7;
-
- enemies[(index)].vitals.x+=enemy_dx;
- enemies[(index)].vitals.y+=enemy_dy;
-
- enemies[(index)].state = EVADING;
-
- Translate_Enemy((index), enemy_dx, enemy_dy);
- }
- else
- if ((enemy_distance<500L) ||
- (enemies[(index)].state == PURSUING))
- {
- enemies[(index)].state = PURSUING;
-
- in_view = 0;
-
- // if (enemies[(index)].pat_num == 1)
- // {
- // get enemy position to see if player is really
- // in it's sights...
-
- in_view=Enemy_Line_Of_Sight(enemies[(index)].vitals.x,
- enemies[(index)].vitals.y,
- enemies[(index)].vitals.angle,
- enemy_distance);
- // }
-
- if (((rand()%15) < 3) && in_view) //(in_view)
- {
- enemies[(index)].state = FIRING;
-
- if (digital_enabled)
- {
- Sound_Stop();
- Sound_Play((sound_ptr)&global_sounds[3]);
- }
-
- Damage = 250/enemy_distance;
-
- if (Damage > 5) Damage = 5;
- Player_Strength -= Damage;
-
- Red_Factor = 63-(Player_Strength>>1);
- color_all.red = Red_Factor;
- color_all.blue = 0;
- color_all.green = 0;
-
- Write_Color_Reg(0, (RGB_color_ptr)&color_all);
- // Red_Factor++;
-
- // if (Red_Factor == 64)
- // Red_Factor = 16;
-
- Restore_Black = 1;
-
- }
-
- tempor = enemies[(index)].vitals.angle;
-
- enemy_dx=cos(6.28*tempor/ANGLE_360)*7;
- enemy_dy=sin(6.28*tempor/ANGLE_360)*7;
-
- enemies[(index)].vitals.x+=enemy_dx;
- enemies[(index)].vitals.y+=enemy_dy;
-
- Translate_Enemy((index), enemy_dx, enemy_dy);
- }
- }
-
- }
-
- pat_start = Restore_Black;
-
- } // end Process_Enemy_Events
-
- /////////////////////////////////////////////////////////
-
- void New_Game(void)
- {
- int scale;
-
- Player_Strength = 63;
- Got_Rapid_Fire = 0;
-
- Player_Ammo = 28;
-
- which_map = 0;
-
- Level_Select(which_map);
-
- x=(8<<CELL_X_SIZE_FP)+(CELL_X_SIZE>>1);
- y=(8<<CELL_X_SIZE_FP)+(CELL_X_SIZE>>1);
- view_angle=ANGLE_60;
-
- Make_Gray_Palette();
-
- // build the scaler table. This table holds MAX_SCALE different arrays. Each
- // array consists of the pre-computed indices for an object to be scaled
-
- for (scale=1; scale<=WINDOW_HALF_HEIGHT; scale++)
- {
-
- // create the indices for this scale
-
- Create_Scale_Data(scale, (int *)scale_table[scale]);
-
- } // end for scale
-
- // THE SECOND Create_Scale_Data FUNCTION REFERED TO HERE IS USED
- // TO COMPUTE SCALES FOR CASES WHERE THE BOTTOM AND THE TOP OF A WALL
- // SLIVER ARE BEYOND THE VERTICAL EXTENTS OF THE VIEWPORT!
-
- for (scale=WINDOW_HALF_HEIGHT+1; scale<=MAX_SCALE; scale++)
- {
-
- // create the indices for this scale
-
- Create_Scale_Data2(scale, (int *)scale_table[scale]);
-
- } // end for scale
-
- beat_it = 0;
- }
-
- void Level_Just_Map(int lev_number)
- {
- FILE *fp, *fopen();
- int ob_num,gunner_num;
-
- int index,row,column;
- char buffer[WORLD_COLUMNS+2],ch;
- int door_num = 0;
- int result;
- long pos;
-
- // open the file
-
- if (!(fp = fopen("world.dat","r")))
- return(0);
-
- pos = (1088L*(long)(lev_number<<1));
- result = fseek( fp, pos, SEEK_SET);
- if( result )
- Print_String_Mode_Y(10,10,79,"Fseek failure",0);
-
- // load in the data
-
- for (row=0; row<WORLD_ROWS; row++)
- {
- // load in the next row
-
- for (column=0; column<WORLD_COLUMNS; column++)
- {
-
- while((ch = getc(fp))==10){} // filter out CR
-
- // translate character to integer
-
- if (ch == ' ')
- ch=0;
- else
- ch = ch - '0';
-
- // insert data into world
-
- if (ch==4)
- world[(WORLD_ROWS-1) - row][column].block_type = 0;
- else
- world[(WORLD_ROWS-1) - row][column].block_type = ch;
-
- Block_Map[(WORLD_ROWS-1) - row][column] = ch;
-
-
- if ((ch == 2) || (ch == 3)) // if it's a door
- {
- world[(WORLD_ROWS-1) - row][column].door_id = door_num;
-
-
- doors[door_num].door_y = (WORLD_ROWS-1) - row;
- doors[door_num].door_x = column;
- doors[door_num].door_state = CLOSED;
- doors[door_num].door_block_type = ch;
- doors[door_num].locked=0;
- doors[door_num].door_speed=5;
- doors[door_num].door_increment=0;
- doors[door_num].door_wait_to_close=0;
-
- door_num++;
- }
- } // end for column
-
- // process the row
-
- } // end for row
-
- total_world_doors = door_num; // used by Process_Doors
-
- fclose(fp);
-
- if (which_map<4)
- {
- rotate_em = 1;
- Make_Gray_Palette();
- }
- else
- {
- rotate_em = 0;
- Make_Light_Metallic_Blue_Palette();
- }
- }
-
- int Load_Game(void)
- {
- FILE *fp, *fopen();
- int looper, Cur[10];
- int numb = 0, scale;
- char buff[14]="player_d.at";
-
-
- if (!(fp = fopen("plynames.dat","rb")))
- {
- Print_String_Mode_Y(20,150,170,"No saved games on record...",0);
- Print_String_Mode_Y(20,170,170,"...press space...",0);
- while(!keyboard_state[MAKE_SPACE]){};
- Print_String_Mode_Y(20,150,0,"No saved games on record...",0);
- Print_String_Mode_Y(20,170,0,"...press space...",0);
-
- return(1);
- }
- else
- {
- fread(names, sizeof(name_obj)*5, 1, fp);
-
- Refresh_Name_List(170);
- fclose(fp);
-
- while(keyboard_state[MAKE_2] || keyboard_state[MAKE_3]);
-
- numb = Slot_Selection();
- buff[11] = (char)(numb+49);
-
- }
-
- Refresh_Name_List(0);
-
-
- if ((fp = fopen(buff,"rb")))
- {
- fread(Cur, sizeof(Cur), 1, fp);
-
- Player_Strength=Cur[0];
- Player_Ammo=Cur[1];
- which_map=Cur[2];
- Got_Rapid_Fire=Cur[3];
- x=Cur[4];
- y=Cur[5];
- view_angle=Cur[6];
- Number_Of_Fixed_Objects=Cur[7];
- Number_Of_Enemies=Cur[8];
- total_world_doors=Cur[9];
-
- fread(initial_object_list, sizeof(objects)*Number_Of_Fixed_Objects, 1, fp);
- fread(enemies, sizeof(enemy_objects)*Number_Of_Enemies, 1, fp);
- Level_Just_Map(which_map);
-
- fread(doors, sizeof(doors)*total_world_doors, 1, fp);
-
- fclose(fp);
-
- }
-
- for (looper=0; looper < total_world_doors; looper++)
- {
- if (doors[looper].door_state == OPEN)
- {
- world[doors[looper].door_y][doors[looper].door_x].block_type = 0;
-
- // Allow the player to pass through the vacant doorway
-
- Block_Map[doors[looper].door_y][doors[looper].door_x] = 0;
- }
- }
-
- // build the scaler table. This table holds MAX_SCALE different arrays. Each
- // array consists of the pre-computed indices for an object to be scaled
-
- for (scale=1; scale<=WINDOW_HALF_HEIGHT; scale++)
- {
-
- // create the indices for this scale
-
- Create_Scale_Data(scale, (int *)scale_table[scale]);
-
- } // end for scale
-
- // THE SECOND Create_Scale_Data FUNCTION REFERED TO HERE IS USED
- // TO COMPUTE SCALES FOR CASES WHERE THE BOTTOM AND THE TOP OF A WALL
- // SLIVER ARE BEYOND THE VERTICAL EXTENTS OF THE VIEWPORT!
-
- for (scale=WINDOW_HALF_HEIGHT+1; scale<=MAX_SCALE; scale++)
- {
-
- // create the indices for this scale
-
- Create_Scale_Data2(scale, (int *)scale_table[scale]);
-
- } // end for scale
-
-
- Update_Weapon_Statis_Display(Player_Ammo/4);
-
- Update_Life_Statis_Display(Player_Strength/4);
-
- beat_it = 0;
-
- switch(which_map)
- {
- case 0:sprintf(where_am_i,"...somewhere in map 1");break;
- case 1:sprintf(where_am_i,"...somewhere in map 2");break;
- case 2:sprintf(where_am_i,"...somewhere in map 3");break;
- case 3:sprintf(where_am_i,"...somewhere in map 4");break;
- case 4:sprintf(where_am_i,"...somewhere in map 5");break;
- default:break;
- } //end switch
- }
-
- int Slot_Selection(void)
- {
- int done = 0;
-
- while(!done)
- {
- if (keyboard_state[MAKE_1])
- return(0);
-
- if (keyboard_state[MAKE_2])
- return(1);
-
- if (keyboard_state[MAKE_3])
- return(2);
-
- if (keyboard_state[MAKE_4])
- return(3);
-
- if (keyboard_state[MAKE_5])
- return(4);
- }
- } // end Slot_Selection
-
- void Refresh_Name_List(int what_shade)
- {
- Print_String_Mode_Y(10,30,what_shade,"1.",0);
- Print_String_Mode_Y(10,40,what_shade,"2.",0);
- Print_String_Mode_Y(10,50,what_shade,"3.",0);
- Print_String_Mode_Y(10,60,what_shade,"4.",0);
- Print_String_Mode_Y(10,70,what_shade,"5.",0);
- Print_String_Mode_Y(30,30,what_shade,names[0].name,0);
- Print_String_Mode_Y(30,40,what_shade,names[1].name,0);
- Print_String_Mode_Y(30,50,what_shade,names[2].name,0);
- Print_String_Mode_Y(30,60,what_shade,names[3].name,0);
- Print_String_Mode_Y(30,70,what_shade,names[4].name,0);
- }
-
- void Save_Game(void)
- {
- FILE *fp, *fopen();
- int looper, Cur[10];
- int numb = 0;
- char buff[14]="player_d.at", ch;
- int character;
- int done = 0;
- int sel_choice;
-
- if (!(fp = fopen("plynames.dat","rb")))
- {
- sprintf(names[0].name,"Unused Slot");
- sprintf(names[1].name,"Unused Slot");
- sprintf(names[2].name,"Unused Slot");
- sprintf(names[3].name,"Unused Slot");
- sprintf(names[4].name,"Unused Slot");
- }
- else
- {
- fread(names, sizeof(name_obj)*5, 1, fp);
- }
-
- Refresh_Name_List(170);
-
- Print_String_Mode_Y(10,10,170,"Select a slot #",0);
-
- while(keyboard_state[MAKE_2]);
-
- sel_choice = Slot_Selection();
- buff[11] = (char)(sel_choice+49);
-
- // if (!strncmp( names[sel_choice].name, "Unused Slot", 11 ))
- sprintf(names[sel_choice].name," ");
-
- // while(keys_active);
-
- Refresh_Name_List(170);
-
- Keyboard_Remove_Driver();
-
- character = 0;
- done = 0;
-
- while(!done)
- {
-
- ch = getch();
-
- if (ch == 13)
- done = 1;
- else
- if (ch == 8)
- {
- --character;
- if (character < 0) character = 0;
- else names[sel_choice].name[character]=32;
-
- Refresh_Name_List(170);
-
-
- }
- else
- {
- keys_active = 0;
-
- if (character < 11)
- {
- names[sel_choice].name[character] = ch;
-
-
- ++character;
-
- Refresh_Name_List(170);
- }
- if (character>11) character = 11;
- }
- }
-
- Keyboard_Install_Driver();
-
- Refresh_Name_List(0);
-
- fp = fopen("plynames.dat","wb");
- fwrite(names, sizeof(name_obj)*5, 1, fp);
- fclose(fp);
-
-
- Cur[0]=Player_Strength;
- Cur[1]=Player_Ammo;
- Cur[2]=which_map;
- Cur[3]=Got_Rapid_Fire;
- Cur[4]=x;
- Cur[5]=y;
- Cur[6]=view_angle;
- Cur[7]=Number_Of_Fixed_Objects;
- Cur[8]=Number_Of_Enemies;
- Cur[9]=total_world_doors;
-
- if ((fp = fopen(buff,"wb")))
- {
- fwrite(Cur, sizeof(Cur), 1, fp);
- fwrite(initial_object_list, sizeof(objects)*Number_Of_Fixed_Objects, 1, fp);
- fwrite(enemies, sizeof(enemy_objects)*Number_Of_Enemies, 1, fp);
- fwrite(doors, sizeof(doors)*total_world_doors, 1, fp);
- fclose(fp);
-
- }
-
- } // end Save_Game
-
- void Rotate_Em(int well)
- {
- static int color_counter = -1;
-
- if (well==0) return;
-
- color_counter++;
-
- if (well == 1)
- {
- if ((color_counter >= 0) && (color_counter<40))
- Make_Gray_Palette_OAAT(color_counter-0,1);
- if ((color_counter >= 40) && (color_counter<80))
- Make_Blue_Palette_OAAT(color_counter-40,1);
- if ((color_counter >= 80) && (color_counter<120))
- Make_Gray_Palette_OAAT(color_counter-80,1);
- if ((color_counter >= 120) && (color_counter<160))
- Make_Cyan_Palette_OAAT(color_counter-120,1);
- if ((color_counter >= 160) && (color_counter<200))
- Make_Gray_Palette_OAAT(color_counter-160,1);
- if ((color_counter >= 200) && (color_counter<240))
- Make_Gold_Palette_OAAT(color_counter-200,1);
- if (color_counter >= 240)
- color_counter = -1;
- }
- else
- if (well == 2)
- {
- if ((color_counter >= 0) && (color_counter<40))
- Make_Gray_Palette_OAAT(color_counter-1,1);
- if ((color_counter >= 40) && (color_counter<80))
- Make_Blue_Palette_OAAT(color_counter-40,1);
- if ((color_counter >= 41) && (color_counter<81))
- Make_Blue_Palette_OAAT(color_counter-41,1);
- if ((color_counter >= 80) && (color_counter<120))
- Make_Cyan_Palette_OAAT(color_counter-80,1);
- if ((color_counter >= 81) && (color_counter<121))
- Make_Cyan_Palette_OAAT(color_counter-81,1);
- if ((color_counter >= 120) && (color_counter<160))
- Make_Gold_Palette_OAAT(color_counter-120,1);
- if ((color_counter >= 121) && (color_counter<161))
- Make_Gold_Palette_OAAT(color_counter-121,1);
- if (color_counter >= 161)
- color_counter = -1;
- }
- else
- if (well == 3)
- {
- if ((color_counter >= 0) && (color_counter<40))
- Make_Gray_Palette_OAAT(color_counter-0,0);
- if ((color_counter >= 40) && (color_counter<80))
- Make_Blue_Palette_OAAT(color_counter-40,1);
- if ((color_counter >= 41) && (color_counter<81))
- Make_Gold_Palette_OAAT(color_counter-41,0);
- if ((color_counter >= 51) && (color_counter<91))
- Make_Blue_Palette_OAAT(color_counter-51,1);
- if (color_counter >= 91)
- color_counter = -1;
- }
- else
- if (well == 4)
- {
- Make_Light_Metallic_Blue_Palette();
- rotate_em = 0;
- }
- } // end Rotate_Em
-
- // M A I N ///////////////////////////////////////////////////////////////////
-
- int main(int argc, char **argv)
- {
- char buffer[80];
-
- long player_weapon_trajectory, enemy_distance;
-
- int x_door,y_door,feel_x,feel_y;
- int done=0;
- int sequence;
- int scaler,Did_he=0;
-
- int show_help = 0;
-
- int choose, frames;
-
- long tempor;
-
- int index;
- int fat;
- long query;
-
- int sub_array[7];
- int how_long=0;
- int obj_id, obj_threshold;
-
- int just_print_mess;
-
- int sub_view_angle;
-
- int color_counter = 0;
-
- long dx,dy;
-
- FILE *file_pointer, *fopen();
-
- int old_weapon_statis, new_weapon_statis;
-
- int old_life_statis, new_life_statis;
-
-
- // beginning of code
-
- color_floor = 8;
- color_floor = color_floor | (color_floor << 8);
-
- color_ceil = 0;
- color_ceil = color_ceil | (color_ceil << 8);
-
- color_1 = 8;
- color_1 = color_1 | (color_1 << 8);
- color_1 = color_1 | (color_1 << 16);
-
- // seed random number generator
-
- srand(13);
-
- printf("\"\Slow Runnings\"\ version 1.5 is FREEWARE by James McCue.\n");
- printf("Slow Runnings - Copyright 1997!\n");
- printf("\nPress any key to continue...");
-
- getch();
-
- just_print_mess = Parse_Commands(argc,argv);
-
- if (music_enabled)
- {
- Music_Load("test.xmi",(music_ptr)&song);
-
- Music_Play((music_ptr)&song,0);
- }
-
- Keyboard_Install_Driver();
-
- Set_Mode_Y();
-
- _outp(CRT_CONTROLLER,CRT_ADDR_LOW);
- _outp(CRT_CONTROLLER+1,0x00);
-
- Set_Visual_Page_Mode_Y_Half(mode_y_page);
-
- mode_y_page = !mode_y_page;
-
- Load_PCX_and_Page_Flip("opening.pcx",1);
-
- while (!keys_active);
-
- Fade_to_Black_and_Paint_Both(SCREEN_DARKNESS);
- Paint_All_Four_Black();
-
- Load_PCX_and_Page_Flip("story1.pcx",1);
-
- Make_Blue_Palette();
-
- while (!keys_active);
-
- Load_PCX_and_Page_Flip("story2.pcx",0);
-
- while (!keys_active);
-
- Load_PCX_and_Page_Flip("story3.pcx",0);
-
- while (!keys_active);
-
- Load_PCX_and_Page_Flip("story4.pcx",0);
-
- while (!keys_active);
-
- Load_PCX_and_Page_Flip("story5.pcx",0);
-
-
- while (!keys_active);
-
- Fade_to_Black_and_Paint_Both(SCREEN_DARKNESS);
- Paint_All_Four_Black();
-
-
- sprintf(buffer,"Beginning Initialization");
- Print_String_Mode_Y(10,10,170,buffer,0);
-
- Wait_Display_Mode();
-
- Set_Visual_Page_Mode_Y_Half(mode_y_page);
-
- mode_y_page = !mode_y_page;
-
- PCX_Init((pcx_picture_ptr)&image_pcx);
-
- PCX_Load("backw2.pcx", (pcx_picture_ptr)&image_pcx,1);
-
- PCX_Copy_To_Video_Mem((pcx_picture_ptr)&image_pcx, pagey_0_buffer);
-
- PCX_Delete((pcx_picture_ptr)&image_pcx);
-
-
- PCX_Init((pcx_picture_ptr)&image_pcx);
-
- PCX_Load("keyhelp.pcx", (pcx_picture_ptr)&image_pcx,0);
-
- PCX_Copy_To_Video_Mem((pcx_picture_ptr)&image_pcx, pagey_2_buffer);
-
- PCX_Delete((pcx_picture_ptr)&image_pcx);
-
- sprintf(buffer,"Background to Vid Mem - done!");
- Print_String_Mode_Y(10,20,170,buffer,0);
-
- // render initial view
-
- Load_64x64_Sprites((sprite_ptr)&wall_frames,"objectmp.pcx",12);
- Load_64x64_Sprites((sprite_ptr)&ob_frames,"objects.pcx",5);
- Load_64x64_Sprites((sprite_ptr)&duck_frames,"multi2.pcx",11);
- Load_64x64_Sprites((sprite_ptr)&duck_death,"multid.pcx",4);
- Load_64x64_Sprites((sprite_ptr)&the_gun,"thegun.pcx",8);
-
- the_gun.x = 128;
- the_gun.y = 88;
- the_gun.curr_frame = 0;
-
- // load in the textures
-
-
- sprintf(buffer,"Keyboard Driver Installed");
- Print_String_Mode_Y(10,50,170,buffer,0);
-
- // initialize sound system
-
- Allocate_World();
-
- sprintf(buffer,"Level Allocated");
- Print_String_Mode_Y(10,60,170,buffer,0);
-
- // build all the lookup tables
- if ((file_pointer = fopen("data.pov","rb")))
- {
- fread(sub_array, sizeof(sub_array), 1, file_pointer);
-
- my_size = sub_array[0];
- COLUMN_OFFSET = sub_array[1];
- my_height= sub_array[2];
- my_left = sub_array[3];
- my_right = sub_array[4];
- my_v_scale = sub_array[5];
- choose = sub_array[6];
-
- fclose(file_pointer);
-
- }
-
- Build_Tables();
-
- sprintf(buffer,"Trig/Scale tables made.");
- Print_String_Mode_Y(10,70,170,buffer,0);
-
- which_map = 0;
-
- Init_Objects();
-
- Level_Select(which_map);
-
- x=(8<<CELL_X_SIZE_FP)+(CELL_X_SIZE>>1);
- y=(8<<CELL_X_SIZE_FP)+(CELL_X_SIZE>>1);
- view_angle=ANGLE_60;
-
-
- sprintf(buffer,"Map Loaded...");
- Print_String_Mode_Y(10,80,170,buffer,0);
-
-
- // Number_Of_Movable_Objects = 0;
- sprintf(buffer,"Remember 'K' for keyboard help!");
- Print_String_Mode_Y(35,125,252,buffer,0);
-
- sprintf(buffer,"Press any key to Play.");
- Print_String_Mode_Y(70,185,253,buffer,0);
-
- while(!keys_active);
-
- Wait_Display_Mode();
-
- Set_Visual_Page_Mode_Y_Half(PAGE_3);
-
- Wait_Retrace_Mode();
-
- Set_Working_Page_Mode_Y(PAGE_3);
-
- Print_String_Mode_Y(40,80,170,"1. New Game",0);
- Print_String_Mode_Y(40,120,170,"2. Load Game",0);
-
- keys_active = 0;
-
- if (keys_active < 0) keys_active = 0;
-
- fat = 0;
-
- while(!fat)
- {
-
- if(keyboard_state[MAKE_1])
- {
- Print_String_Mode_Y(40,80,0,"1. New Game",0);
- Print_String_Mode_Y(40,120,0,"2. Load Game",0);
- New_Game();
- fat=1;
-
- }
- if(keyboard_state[MAKE_2])
- {
- Print_String_Mode_Y(40,80,0,"1. New Game",0);
- Print_String_Mode_Y(40,120,0,"2. Load Game",0);
- Load_Game();
- how_long=18;
- fat=1;
-
- }
- }
-
- Wait_Display_Mode();
-
- Set_Visual_Page_Mode_Y_Half(PAGE_3);
-
- mode_y_page = !mode_y_page;
-
- fat = 0;
-
- mode_y_page = PAGE_0;
-
- for (index = 0; index <=255; index++)
- Read_Color_Reg(index, (RGB_color_ptr)&old_all[index]);
-
- // Start by copying bitmap to both pages
-
- Wait_Display_Mode();
-
- Set_Visual_Page_Mode_Y_Half(mode_y_page);
-
- mode_y_page = !mode_y_page;
-
- Setup_Initial_Display();
-
- Ray_Caster();
-
- // Weak_Attempt();
-
- Draw_Walls();
-
- Setup_Initial_Display();
-
- if (digital_enabled)
- {
- Sound_Load("pickup.voc",(sound_ptr)&global_sounds[0],1);
- Sound_Load("plyrshot.voc",(sound_ptr)&global_sounds[1],1);
- Sound_Load("boom.voc",(sound_ptr)&global_sounds[2],1);
- Sound_Load("enemshot.voc",(sound_ptr)&global_sounds[3],1);
- Sound_Load("nextmap.voc",(sound_ptr)&global_sounds[4],1);
- Sound_Load("dooropen.voc",(sound_ptr)&global_sounds[5],1);
- Sound_Load("click.voc",(sound_ptr)&global_sounds[6],1);
- }
-
- Ray_Caster();
-
- // Weak_Attempt();
-
- Draw_Walls();
-
- // wait for user to press ESC to quit
-
- if (music_enabled)
- {
- Music_Stop();
-
- if (which_map<4)
- Music_Play((music_ptr)&song,1);
- else
- Music_Play((music_ptr)&song,2);
- }
-
- Begin_Object_List();
-
- color_counter =-1;
-
- query = Timer_Query();
-
- while(!done)
- {
- Process_Doors();
-
- while ((Timer_Query() - query)<1);
-
- query = Timer_Query();
-
- Wait_Display_Mode();
-
- Set_Visual_Page_Mode_Y_Half(mode_y_page);
-
- if (pat_start)
- {
- if (pat_start<2)
- {
- Process_Flashes();
- ++pat_start;
- }
- else
- pat_start = 0;
- }
-
- if (rotate_em)
- {
- Rotate_Em(which_map);
-
- } // end if rotate_em
-
- old_weapon_statis = Player_Ammo / 4;
-
- old_life_statis = Player_Strength /4;
-
- if (Did_he)
- {
- for (index = 0; index <= 255; index++)
- {
- Write_Color_Reg(index, (RGB_color_ptr)&old_all[index]);
-
- }
-
- Did_he=0;
- }
-
- Did_he = Did_Player_Die();
-
- mode_y_page = !mode_y_page;
-
- dx=dy=0;
-
- if (keyboard_state[MAKE_SPACE])
- {
- // test if there is a door in front of player
-
- // project a "feeler" 3 steps in front of player and test for a door
-
- x_door = (int)(x + cos(6.28*view_angle/ANGLE_360)*3*15);
- y_door = (int)(y + sin(6.28*view_angle/ANGLE_360)*3*15);
-
- // compute cell position
-
- feel_x = x_door/CELL_X_SIZE;
- feel_y = y_door/CELL_Y_SIZE;
-
- // test for door
-
- if ((world[feel_y][feel_x].block_type == 2) || (world[feel_y][feel_x].block_type == 3))
- {
- id_number = world[feel_y][feel_x].door_id;
-
- if ((doors[id_number].door_state == CLOSED) ||
- (doors[id_number].door_state == CLOSING))
- {
-
- if (doors[id_number].door_state == CLOSED)
- {
- if (digital_enabled)
- {
- Sound_Stop();
- Sound_Play((sound_ptr)&global_sounds[0]);
- }
-
- }
- // make door disappear by starting process
-
- doors[id_number].door_y = feel_y;
- doors[id_number].door_x = feel_x;
- doors[id_number].door_state = OPENING;
- doors[id_number].door_increment += 6;
-
- }
- } // end if a door was found
- else
- if (world[feel_y][feel_x].block_type==7)
- {
- if (digital_enabled)
- {
- Sound_Stop();
- Sound_Play((sound_ptr)&global_sounds[4]);
- }
-
- x=(8<<CELL_X_SIZE_FP)+(CELL_X_SIZE>>1);
- y=(8<<CELL_X_SIZE_FP)+(CELL_X_SIZE>>1);
- view_angle=ANGLE_60;
-
- ++which_map;
-
- if (which_map == 5)
- {
- at_end = 1;
- really_at_end = 1;
- done = 1;
- while(keyboard_state[MAKE_SPACE]){};
- }
- else
- {
- if(which_map<4)
- {
- Level_Select(which_map);
- }
- else
- {
- Level_Select(which_map);
- if (music_enabled)
- {
- Music_Stop();
-
- Music_Play((music_ptr)&song,2);
- }
- }
- }
-
- }
- else
- if (world[feel_y][feel_x].block_type==9)
- {
- if (digital_enabled)
- {
- Sound_Stop();
- Sound_Play((sound_ptr)&global_sounds[4]);
- }
-
- x=(8<<CELL_X_SIZE_FP)+(CELL_X_SIZE>>1);
- y=(8<<CELL_X_SIZE_FP)+(CELL_X_SIZE>>1);
- view_angle=ANGLE_60;
-
- if (which_map == 4)
- {
- at_end = 1;
- really_at_end = 1;
- done = 1;
- while(keyboard_state[MAKE_SPACE]){};
- }
-
- }
- }
-
- if (keyboard_state[MAKE_F])
- {
- if (player_state==PLAYER_NOT_FIRING)
- {
- if (digital_enabled)
- {
- Sound_Stop();
-
- if (Player_Ammo)
- Sound_Play((sound_ptr)&global_sounds[1]);
- else
- Sound_Play((sound_ptr)&global_sounds[6]);
- }
-
- player_state = PLAYER_FIRING;
- }
-
- if ((player_state==PLAYER_FIRING) && (the_gun.curr_frame > 5) && (Got_Rapid_Fire))
- {
- if (digital_enabled)
- {
- Sound_Stop();
- if (Player_Ammo)
- Sound_Play((sound_ptr)&global_sounds[1]);
- else
- Sound_Play((sound_ptr)&global_sounds[6]);
- }
-
- the_gun.curr_frame = 2;
- }
- }
-
- if (keyboard_state[MAKE_P])
- {
- Print_String_Mode_Y(20,70,255,"Paused - press SPACE to continue...",1);
-
- while (!keyboard_state[MAKE_SPACE]);
- }
-
- if (keyboard_state[MAKE_K])
- {
- Wait_Display_Mode();
-
- Set_Visual_Page_Mode_Y_Half(PAGE_2);
-
- while (!keyboard_state[MAKE_G]) {};
-
- Wait_Display_Mode();
-
- Set_Visual_Page_Mode_Y_Half(!mode_y_page);
-
- }
-
- if (keyboard_state[MAKE_F5])
- {
- Wait_Display_Mode();
-
- Set_Visual_Page_Mode_Y_Half(PAGE_3);
-
- Wait_Retrace_Mode();
-
- Set_Working_Page_Mode_Y(PAGE_3);
-
- Print_String_Mode_Y(40,80,170,"1. New Game",0);
- Print_String_Mode_Y(40,100,170,"2. Save Game",0);
- Print_String_Mode_Y(40,120,170,"3. Load Game",0);
-
- while(!fat)
- {
- if(keyboard_state[MAKE_1])
- {
- Print_String_Mode_Y(40,80,0,"1. New Game",0);
- Print_String_Mode_Y(40,100,0,"2. Save Game",0);
- Print_String_Mode_Y(40,120,0,"3. Load Game",0);
- New_Game();
- fat=1;
- }
- if(keyboard_state[MAKE_2])
- {
- Print_String_Mode_Y(40,80,0,"1. New Game",0);
- Print_String_Mode_Y(40,100,0,"2. Save Game",0);
- Print_String_Mode_Y(40,120,0,"3. Load Game",0);
- Save_Game();
- fat=1;
- }
- if(keyboard_state[MAKE_3])
- {
- Print_String_Mode_Y(40,80,0,"1. New Game",0);
- Print_String_Mode_Y(40,100,0,"2. Save Game",0);
- Print_String_Mode_Y(40,120,0,"3. Load Game",0);
- Load_Game();
-
- if (music_enabled)
- {
- Music_Stop();
-
- if (which_map<4)
- Music_Play((music_ptr)&song,1);
- else
- Music_Play((music_ptr)&song,2);
- }
-
- how_long=18;
- fat=1;
- }
-
- }
-
- mode_y_page = !mode_y_page;
-
- Wait_Display_Mode();
-
- Set_Visual_Page_Mode_Y_Half(mode_y_page);
-
- mode_y_page = !mode_y_page;
-
- fat = 0;
- }
- if (keyboard_state[MAKE_RIGHT])
- {
- if ((view_angle-=ANGLE_7)<ANGLE_0)
- view_angle+=ANGLE_360;
-
- sub_view_angle = view_angle + ANGLE_90;
- if (sub_view_angle>=ANGLE_360)
- sub_view_angle-=ANGLE_360;
-
- // move player along view vector foward
-
- dx=cos(6.28*sub_view_angle/ANGLE_360)*3;
- dy=sin(6.28*sub_view_angle/ANGLE_360)*3;
-
- x+=dx;
- y+=dy;
-
- Translate_Player(dx, dy);
- }
-
- if (keyboard_state[MAKE_LEFT])
- {
- if ((view_angle+=ANGLE_7)>=ANGLE_360)
- view_angle-=ANGLE_360;
-
- sub_view_angle = view_angle - ANGLE_90;
- if (sub_view_angle<0)
- sub_view_angle+=ANGLE_360;
-
- // move player along view vector foward
-
- dx=cos(6.28*sub_view_angle/ANGLE_360)*3;
- dy=sin(6.28*sub_view_angle/ANGLE_360)*3;
-
- x+=dx;
- y+=dy;
-
- Translate_Player(dx, dy);
- }
-
-
- if (keyboard_state[MAKE_UP] || keyboard_state[MAKE_DOWN])
- {
- if (keyboard_state[MAKE_UP])
- {
-
- // move player along view vector foward
-
- dx=cos(6.28*view_angle/ANGLE_360)*15;
- dy=sin(6.28*view_angle/ANGLE_360)*15;
-
- x+=dx;
- y+=dy;
-
- }
-
- if (keyboard_state[MAKE_DOWN])
- {
- // move player along view vector backward
-
- dx=-cos(6.28*view_angle/ANGLE_360)*15;
- dy=-sin(6.28*view_angle/ANGLE_360)*15;
-
- x+=dx;
- y+=dy;
-
- }
-
- Translate_Player(dx, dy);
- } // end if player in motion
-
- if (keyboard_state[MAKE_C] || keyboard_state[MAKE_V])
- {
- if (keyboard_state[MAKE_C])
- {
- sub_view_angle = view_angle + ANGLE_90;
- if (sub_view_angle>ANGLE_360)
- sub_view_angle-=ANGLE_360;
-
- // move player along view vector foward
-
- dx=cos(6.28*sub_view_angle/ANGLE_360)*10;
- dy=sin(6.28*sub_view_angle/ANGLE_360)*10;
-
- x+=dx;
- y+=dy;
-
- }
-
- if (keyboard_state[MAKE_V])
- {
- sub_view_angle = view_angle - ANGLE_90;
- if (sub_view_angle<0)
- sub_view_angle+=ANGLE_360;
-
- // move player along view vector backward
-
- dx=cos(6.28*sub_view_angle/ANGLE_360)*10;
- dy=sin(6.28*sub_view_angle/ANGLE_360)*10;
-
- x+=dx;
- y+=dy;
-
- }
-
- Translate_Player(dx, dy);
-
- } // end if player in motion
-
-
- if (keyboard_state[MAKE_ESC])
- {
- done=1;
- }
-
- // render the view
-
- // THE FOLLOWING FUNCTION: Ray_Caster(); -has been modified so that
- // the actual drawing is done elsewhere, in order to interleave the
- // ray casting with the time spent waiting for VGA page flipping to
- // take hold!!! Gad Zooks! - IT WORKS!
-
- Ray_Caster();
-
- // Weak_Attempt();
-
-
- /// CODE THAT NEEDS A BATH!
- /////////////////////////////////////////////////////////
- Process_Enemy_Events();
-
- if (just_grabbed_something)
- {
- if (digital_enabled)
- {
- Sound_Stop();
- Sound_Play((sound_ptr)&global_sounds[5]);
- }
-
- pat_start = 1;
-
- for (index = 0; index <= 15; index++)
- {
- Read_Color_Reg(index, (RGB_color_ptr)&color_all);
-
- switch (what_obj)
- {
- case 4:
- {
- color_all.green += 32;
-
- if (color_all.green > 63)
- color_all.green = 63;
- } break;
-
- case 5:
- {
- color_all.green += 32;
-
- if (color_all.green > 63)
- color_all.green = 63;
- } break;
-
- case 6:
- {
- color_all.blue += 32;
-
- if (color_all.blue > 63)
- color_all.blue = 63;
- } break;
- }
-
- Write_Color_Reg(index, (RGB_color_ptr)&color_all);
-
- }
-
-
- for (index = 16; index <= 80; index++)
- {
- Read_Color_Reg(index, (RGB_color_ptr)&old_all[index]);
-
- switch (what_obj)
- {
- case 4:
- {
- color_all.green = old_all[index].green + 32;
-
- if (color_all.green > 63)
- color_all.green = 63;
- } break;
-
- case 5:
- {
- color_all.green = old_all[index].green + 32;
-
- if (color_all.green > 63)
- color_all.green = 63;
- } break;
-
- case 6:
- {
- color_all.blue = old_all[index].blue + 32;
-
- if (color_all.blue > 63)
- color_all.blue = 63;
- } break;
- }
-
- Write_Color_Reg(index, (RGB_color_ptr)&color_all);
-
- }
-
- for (index = 81; index <= 255; index++)
- {
- Read_Color_Reg(index, (RGB_color_ptr)&color_all);
-
- switch (what_obj)
- {
- case 4:
- {
- color_all.green += 32;
-
- if (color_all.green > 63)
- color_all.green = 63;
- } break;
-
- case 5:
- {
- color_all.green += 32;
-
- if (color_all.green > 63)
- color_all.green = 63;
- } break;
-
- case 6:
- {
- color_all.blue += 32;
-
- if (color_all.blue > 63)
- color_all.blue = 63;
- } break;
- }
-
- Write_Color_Reg(index, (RGB_color_ptr)&color_all);
-
- }
-
-
- }
-
- Begin_Object_List();
-
- Find_Object_Distance();
-
- Sort_Object_List();
-
- Wait_Retrace_Mode();
-
- Set_Working_Page_Mode_Y(mode_y_page);
-
- Erase_Scene();
-
- Draw_Walls();
-
- for (index = (Number_Of_Fixed_Objects+Number_Of_Enemies); index >= 0; index--)
- {
- if (object_list[index].dist < 1000)
- {
- if ((object_list[index].kind_of_object == 2) ||
- (object_list[index].kind_of_object == 3))
- {
- obj_id = object_list[index].id_number;
-
- if (enemies[object_list[index].id_number].state == DYING)
- {
- --enemies[object_list[index].id_number].threshold;
-
- if (enemies[object_list[index].id_number].threshold == 0)
- enemies[object_list[index].id_number].state = DEAD;
- }
-
- obj_threshold = enemies[object_list[index].id_number].threshold;
-
- }
-
- Find_and_Maybe_Plot_Objects(object_list[index],obj_id,obj_threshold);
- }
- }
- if (player_state == PLAYER_FIRING)
- {
- ++the_gun.curr_frame;
-
- if ((the_gun.curr_frame == 4) && (Player_Ammo))
- --Player_Ammo;
- else
- if (the_gun.curr_frame == 4)
- ++the_gun.curr_frame;
-
- if (the_gun.curr_frame > 7)
- {
- the_gun.curr_frame = 0;
-
- player_state = PLAYER_NOT_FIRING;
- }
- }
-
- Sprite_Draw_Clip_Special((sprite_ptr)&the_gun, video_buffer);
-
- new_weapon_statis = Player_Ammo / 4;
-
- if (new_weapon_statis!=old_weapon_statis)
- Update_Weapon_Statis_Display(new_weapon_statis);
-
- new_life_statis = Player_Strength / 4;
-
- if (new_life_statis!=old_life_statis)
- Update_Life_Statis_Display(new_life_statis);
-
- if (doors[0].door_state != CLOSED && which_map==4 && !beat_it)
- {
- Make_Gold_Palette();
- beat_it = 1;
- }
-
- if (doors[0].door_state != CLOSED && which_map==4)
- {
- sprintf(buffer,"You have not seen the last of me!");
- Print_String_Mode_Y(15,15,170,buffer,1);
- sprintf(buffer,"hmmm... actually - you haven't");
- Print_String_Mode_Y(15,25,170,buffer,1);
- sprintf(buffer,"even seen me YET!...oh well...");
- Print_String_Mode_Y(15,35,170,buffer,1);
- }
-
- if(how_long)
- {
- Print_String_Mode_Y(15,20,255,where_am_i,1);
- --how_long;
- }
- } //end while
-
- // De-allocate Memory
-
- Sprite_Delete((sprite_ptr)&wall_frames);
-
- Sprite_Delete((sprite_ptr)&duck_frames);
-
- Sprite_Delete((sprite_ptr)&duck_death);
-
- Sprite_Delete((sprite_ptr)&ob_frames);
-
- Sprite_Delete((sprite_ptr)&the_gun);
-
- // free memory associated with lookup tables...
-
- for (index = 0; index < WORLD_ROWS; index++)
- {
- _ffree(Block_Map[index]);
- }
-
- _ffree(tan_table);
- _ffree(inv_tan_table);
- _ffree(x_step);
- _ffree(y_step);
- _ffree(cos_table);
- _ffree(inv_cos_table);
- _ffree(inv_sin_table);
-
- for (scaler=0; scaler<=MAX_SCALE; scaler++)
- {
-
- free(scale_table[scaler]);
-
- } // end for scaler
-
- // pot up the lights...
-
- if (at_end)
- {
- for(index=0; index<20; index++)
- {
- for(pal_reg=0; pal_reg<=255; pal_reg++)
- {
- // get the next color to fade
-
- Read_Color_Reg(pal_reg,(RGB_color_ptr)&color_all);
-
- // test if this color register is already at peak intensity
-
- color_all.red += 4;
-
- // test if this color register is already white
- if (color_all.red > 63)
- color_all.red=63;
-
- color_all.green += 4;
-
- if (color_all.green > 63)
- color_all.green=63;
-
- // set the color to a diminshed intensity
-
- Write_Color_Reg(pal_reg,(RGB_color_ptr)&color_all);
-
- } // end for pal reg
-
- // wait a bit
-
- Time_Delay(1);
-
- } // end for index
- }
- else
- {
- Screen_Transition(SCREEN_WHITENESS);
- }
-
- if (really_at_end)
- {
- if (music_enabled)
- {
- Music_Stop();
-
- Music_Play((music_ptr)&song,3);
- }
-
- mode_y_page = !mode_y_page;
-
- Wait_Retrace_Mode();
-
- Set_Working_Page_Mode_Y(mode_y_page);
-
- // erase the screen
-
- outp(SEQUENCER,SEQ_PLANE_ENABLE);
- outp(SEQUENCER+1,0x0f);
-
- _asm
- {
-
- les di,video_buffer // point es:di to video buffer, same addre for mode Z
- xor ax,ax // zero out AH and AL
- mov cx,320*200/8 // number of words to fill(using word is faster than bytes)
- rep stosw // move the color into the video buffer really fast!
-
- } // end inline asm
-
- Load_PCX_and_Page_Flip("winning.pcx",0);
-
- for (index = 0; index <=15; index++)
- Write_Color_Reg(index, (RGB_color_ptr)&old_all[index]);
-
- for (index = 16; index <= 60; index++)
- {
- color_all.red = 0;
- color_all.green = 0;
- color_all.blue = (index-16);
-
- Write_Color_Reg(index, (RGB_color_ptr)&color_all);
-
- }
-
- for (index = 61; index <=255; index++)
- Write_Color_Reg(index, (RGB_color_ptr)&old_all[index]);
-
- keys_active=0;
-
- while(!keys_active){};
-
-
- Fade_to_Black_and_Paint_Both(FULL_SCREEN_DARKNESS);
-
- }
-
- free(object_list);
- free(initial_object_list);
-
- if (digital_enabled)
- {
- Sound_Stop();
-
- Sound_Unload((sound_ptr)&global_sounds[0]);
- Sound_Unload((sound_ptr)&global_sounds[1]);
- Sound_Unload((sound_ptr)&global_sounds[2]);
- Sound_Unload((sound_ptr)&global_sounds[3]);
- Sound_Unload((sound_ptr)&global_sounds[4]);
- Sound_Unload((sound_ptr)&global_sounds[5]);
- Sound_Unload((sound_ptr)&global_sounds[6]);
-
- }
-
- if (music_enabled)
- {
- Music_Stop();
-
- Music_Unload((music_ptr)&song);
- }
-
- Set_Graphics_Mode(TEXT_MODE);
-
-
- printf("\nProgramming: James McCue!\n");
- printf(" -with the help of the great Andre' Lamothe's BLACK ART OF 3D\n");
- printf("GAME PROGRAMMING (Waite Group Press) graphics library - and his WRITINGS!!!\n\n");
-
- printf("Concept: Not much of one - is there? - by James McCue\n");
- printf("'Art?': Walls, Enemies and most stuff - James McCue\n");
-
- printf("ART: Doors, and that face, That face, THAT COVER GIRL FACE\n");
- printf(" - BY MY BROTHER ROBERT MCCUE\n\n");
-
- printf("If you wish, contact me via e-mail at QBALL1723@AOL.COM\n\n");
-
- printf("This program is completely free, but if you'd wish to contribute to my\n");
- printf("game programming cause... please send $5.00 to:\n\n");
- printf("James McCue, P.O. Box 151, Bethpage, NY 11714-4831\n\n");
-
- printf("Thank you for playing Slow Runnings!\n\n");
- printf("Visit my website: http://members.aol.com/qball1723/index.htm\n\n");
-
- Keyboard_Remove_Driver();
-
- getch();
- return(0);
- } // end main
-
-
-